Skip to content

Commit 6a1639a

Browse files
authored
Merge pull request #60 from springaialibaba/0228-yuluo/add-more-chatclient
feat: update playground code
2 parents 9d12744 + e76c870 commit 6a1639a

File tree

11 files changed

+364
-6
lines changed

11 files changed

+364
-6
lines changed

spring-ai-alibaba-integration-example/backend/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,6 @@ logs/
4141
*.wav
4242
*.png
4343
*.jpg
44+
45+
# ignore db files
46+
/src/main/resources/db/user.db

spring-ai-alibaba-integration-example/backend/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,24 @@
7373
<version>2.15.0</version>
7474
</dependency>
7575

76+
<dependency>
77+
<groupId>org.springframework.boot</groupId>
78+
<artifactId>spring-boot-starter-data-jpa</artifactId>
79+
<version>${spring-boot.version}</version>
80+
</dependency>
81+
82+
<dependency>
83+
<groupId>org.xerial</groupId>
84+
<artifactId>sqlite-jdbc</artifactId>
85+
<version>3.49.1.0</version>
86+
</dependency>
87+
88+
<dependency>
89+
<groupId>org.hibernate.orm</groupId>
90+
<artifactId>hibernate-community-dialects</artifactId>
91+
<version>6.6.9.Final</version>
92+
</dependency>
93+
7694
</dependencies>
7795

7896
<build>

spring-ai-alibaba-integration-example/backend/src/main/java/com/alibaba/cloud/ai/application/aop/UserIpAspect.java

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
package com.alibaba.cloud.ai.application.aop;
1919

20+
import com.alibaba.cloud.ai.application.entity.User;
21+
import com.alibaba.cloud.ai.application.repository.UserRepository;
22+
import com.alibaba.cloud.ai.application.utils.TimeUtils;
2023
import jakarta.servlet.http.HttpServletRequest;
2124
import org.aspectj.lang.annotation.After;
2225
import org.aspectj.lang.annotation.Aspect;
@@ -39,21 +42,46 @@ public class UserIpAspect {
3942

4043
private final HttpServletRequest request;
4144

42-
public UserIpAspect(HttpServletRequest request) {
45+
private final UserRepository userRepository;
46+
47+
public UserIpAspect(
48+
HttpServletRequest request,
49+
UserRepository userRepository
50+
) {
4351
this.request = request;
52+
this.userRepository = userRepository;
4453
}
4554

46-
/**
47-
* Todo: 获取用户 ip 用于统计 apikey 调用次数
48-
*/
4955
@Pointcut("@annotation(com.alibaba.cloud.ai.application.annotation.UserIp)")
5056
public void logUserIp() {
5157
}
5258

5359
@After("logUserIp()")
54-
public void after(){
60+
public void after() {
61+
62+
String userIp = request.getRemoteAddr();
63+
String requestUri = request.getRequestURI();
64+
String requestTime = TimeUtils.getCurrentTime();
65+
66+
logger.info("User IP: {}, Time: {}, Uri: {}", userIp, requestTime, requestUri);
5567

56-
logger.info("User IP: {}", request.getRemoteAddr());
68+
userRepository.findByRequestIp(userIp)
69+
.ifPresentOrElse(
70+
user -> {
71+
user.setRequestCount(user.getRequestCount() + 1);
72+
user.setRequestUri(user.getRequestUri() + ", " + requestUri);
73+
userRepository.save(user);
74+
},
75+
() -> {
76+
User newUser = new User.Builder()
77+
.setRequestUri(requestUri)
78+
.setRequestTime(requestTime)
79+
.setRequestIp(userIp)
80+
.setRequestCount(1)
81+
.build();
82+
userRepository.save(newUser);
83+
}
84+
);
5785
}
5886

5987
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.cloud.ai.application.config;
19+
20+
import java.net.http.HttpClient;
21+
import java.time.Duration;
22+
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
26+
import org.springframework.boot.autoconfigure.AutoConfiguration;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.http.client.JdkClientHttpRequestFactory;
29+
import org.springframework.web.client.RestClient;
30+
31+
/**
32+
* @author yuluo
33+
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
34+
* 解决请求超时问题。
35+
*/
36+
37+
@AutoConfiguration
38+
public class RestConfiguration {
39+
40+
private final Logger logger = LoggerFactory.getLogger(RestConfiguration.class);
41+
42+
private static final Duration READ_TIMEOUT = Duration.ofMinutes(2);
43+
44+
@Bean
45+
public RestClient.Builder restClient() {
46+
47+
logger.warn("RestClient.Builder timeout set to: {}", READ_TIMEOUT);
48+
49+
JdkClientHttpRequestFactory requestFactory = new JdkClientHttpRequestFactory(
50+
HttpClient.newHttpClient()
51+
);
52+
53+
requestFactory.setReadTimeout(READ_TIMEOUT);
54+
55+
return RestClient.builder().requestFactory(requestFactory);
56+
}
57+
58+
}

spring-ai-alibaba-integration-example/backend/src/main/java/com/alibaba/cloud/ai/application/controller/SAAChatController.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public Flux<Result<String>> chat(
7474
@RequestHeader(value = "chatId", required = false) String chatId
7575
) {
7676

77+
// 接口限流在审计平台中配置
78+
7779
if (!ValidText.isValidate(prompt)) {
7880

7981
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.cloud.ai.application.entity;
19+
20+
import jakarta.persistence.Column;
21+
import jakarta.persistence.Entity;
22+
import jakarta.persistence.GeneratedValue;
23+
import jakarta.persistence.GenerationType;
24+
import jakarta.persistence.Id;
25+
import jakarta.persistence.Table;
26+
27+
/**
28+
* @author yuluo
29+
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
30+
*/
31+
32+
@Entity
33+
@Table(name = "users")
34+
public class User {
35+
36+
@Id
37+
@GeneratedValue(strategy = GenerationType.IDENTITY)
38+
private Long id;
39+
40+
@Column(name = "request_time", nullable = false)
41+
private String requestTime;
42+
43+
@Column(name = "request_ip", nullable = false)
44+
private String requestIp;
45+
46+
@Column(name = "request_count", nullable = false)
47+
private int requestCount;
48+
49+
@Column(name = "max_request_count", nullable = false)
50+
private int maxRequestCount = Integer.MAX_VALUE;
51+
52+
@Column(name = "request_uri", nullable = false)
53+
private String requestUri;
54+
55+
// 默认构造函数
56+
public User() {}
57+
58+
// 带参数的构造函数
59+
public User(
60+
String requestTime,
61+
String requestIp,
62+
int requestCount,
63+
String requestUri
64+
) {
65+
this.requestTime = requestTime;
66+
this.requestIp = requestIp;
67+
this.requestCount = requestCount;
68+
this.requestUri = requestUri;
69+
}
70+
71+
public static class Builder {
72+
private String requestTime;
73+
private String requestIp;
74+
private int requestCount;
75+
private String requestUri;
76+
77+
public Builder setRequestTime(String requestTime) {
78+
this.requestTime = requestTime;
79+
return this;
80+
}
81+
82+
public Builder setRequestIp(String requestIp) {
83+
this.requestIp = requestIp;
84+
return this;
85+
}
86+
87+
public Builder setRequestCount(int requestCount) {
88+
this.requestCount = requestCount;
89+
return this;
90+
}
91+
92+
public Builder setRequestUri(String requestUri) {
93+
this.requestUri = requestUri;
94+
return this;
95+
}
96+
97+
public User build() {
98+
return new User(requestTime, requestIp, requestCount, requestUri);
99+
}
100+
}
101+
102+
public Long getId() {
103+
return id;
104+
}
105+
106+
public void setId(Long id) {
107+
this.id = id;
108+
}
109+
110+
public String getRequestTime() {
111+
return requestTime;
112+
}
113+
114+
public void setRequestTime(String requestTime) {
115+
this.requestTime = requestTime;
116+
}
117+
118+
public String getRequestIp() {
119+
return requestIp;
120+
}
121+
122+
public void setRequestIp(String requestIp) {
123+
this.requestIp = requestIp;
124+
}
125+
126+
public int getRequestCount() {
127+
return requestCount;
128+
}
129+
130+
public void setRequestCount(int requestCount) {
131+
this.requestCount = requestCount;
132+
}
133+
134+
public int getMaxRequestCount() {
135+
return maxRequestCount;
136+
}
137+
138+
public void setMaxRequestCount(int maxRequestCount) {
139+
this.maxRequestCount = maxRequestCount;
140+
}
141+
142+
public String getRequestUri() {
143+
return requestUri;
144+
}
145+
146+
public void setRequestUri(String requestUri) {
147+
this.requestUri = requestUri;
148+
}
149+
150+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.alibaba.cloud.ai.application.repository;
2+
3+
import java.util.Optional;
4+
5+
import com.alibaba.cloud.ai.application.entity.User;
6+
7+
import org.springframework.data.jpa.repository.JpaRepository;
8+
import org.springframework.stereotype.Repository;
9+
10+
/**
11+
* @author yuluo
12+
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
13+
*/
14+
15+
@Repository
16+
public interface UserRepository extends JpaRepository<User, Long> {
17+
18+
Optional<User> findByRequestIp(String userIp);
19+
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.cloud.ai.application.utils;
19+
20+
import java.time.Instant;
21+
import java.time.LocalDateTime;
22+
import java.time.ZoneId;
23+
import java.time.format.DateTimeFormatter;
24+
25+
/**
26+
* @author yuluo
27+
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
28+
*/
29+
30+
public final class TimeUtils {
31+
32+
private final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
33+
34+
private TimeUtils() {
35+
}
36+
37+
public static String getCurrentTime() {
38+
39+
long currentTimeMillis = System.currentTimeMillis();
40+
41+
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(currentTimeMillis), ZoneId.systemDefault());
42+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
43+
44+
return dateTime.format(formatter);
45+
}
46+
47+
}

0 commit comments

Comments
 (0)