Skip to content

Commit 56f99cb

Browse files
committed
Fix SonarQube issues
1 parent 9f92543 commit 56f99cb

File tree

3 files changed

+44
-19
lines changed

3 files changed

+44
-19
lines changed

spring-petclinic-genai-service/src/main/java/org/springframework/samples/petclinic/genai/AIFunctionConfiguration.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.util.List;
44
import java.util.function.Function;
55

6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
68
import org.springframework.context.annotation.Bean;
79
import org.springframework.context.annotation.Configuration;
810
import org.springframework.context.annotation.Description;
@@ -27,6 +29,8 @@
2729
@Configuration
2830
class AIFunctionConfiguration {
2931

32+
private static final Logger LOG = LoggerFactory.getLogger(AIFunctionConfiguration.class);
33+
3034
// The @Description annotation helps the model understand when to call the function
3135
@Bean
3236
@Description("List the owners that the pet clinic has")
@@ -49,7 +53,7 @@ public Function<VetRequest, VetResponse> listVets(AIDataProvider petclinicAiProv
4953
return petclinicAiProvider.getVets(request);
5054
}
5155
catch (JsonProcessingException e) {
52-
e.printStackTrace();
56+
LOG.error("Error processing JSON in the listVets function", e);
5357
return null;
5458
}
5559
};

spring-petclinic-genai-service/src/main/java/org/springframework/samples/petclinic/genai/PetclinicChatClient.java

+16-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.DEFAULT_CHAT_MEMORY_CONVERSATION_ID;
44

5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
57
import org.springframework.ai.chat.client.ChatClient;
68
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
79
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
@@ -20,26 +22,28 @@
2022
@RequestMapping("/")
2123
public class PetclinicChatClient {
2224

25+
private static final Logger LOG = LoggerFactory.getLogger(PetclinicChatClient.class);
26+
2327
// ChatModel is the primary interfaces for interacting with an LLM
2428
// it is a request/response interface that implements the ModelModel
2529
// interface. Make suer to visit the source code of the ChatModel and
26-
// checkout the interfaces in the core spring ai package.
30+
// checkout the interfaces in the core Spring AI package.
2731
private final ChatClient chatClient;
2832

2933
public PetclinicChatClient(ChatClient.Builder builder, ChatMemory chatMemory) {
3034
// @formatter:off
3135
this.chatClient = builder
3236
.defaultSystem("""
33-
You are a friendly AI assistant designed to help with the management of a veterinarian pet clinic called Spring Petclinic.
34-
Your job is to answer questions about and to perform actions on the user's behalf, mainly around
35-
veterinarians, owners, owners' pets and owners' visits.
36-
You are required to answer an a professional manner. If you don't know the answer, politely tell the user
37-
you don't know the answer, then ask the user a followup question to try and clarify the question they are asking.
38-
If you do know the answer, provide the answer but do not provide any additional followup questions.
39-
When dealing with vets, if the user is unsure about the returned results, explain that there may be additional data that was not returned.
40-
Only if the user is asking about the total number of all vets, answer that there are a lot and ask for some additional criteria.
41-
For owners, pets or visits - provide the correct data.
42-
""")
37+
You are a friendly AI assistant designed to help with the management of a veterinarian pet clinic called Spring Petclinic.
38+
Your job is to answer questions about and to perform actions on the user's behalf, mainly around
39+
veterinarians, owners, owners' pets and owners' visits.
40+
You are required to answer an a professional manner. If you don't know the answer, politely tell the user
41+
you don't know the answer, then ask the user a followup question to try and clarify the question they are asking.
42+
If you do know the answer, provide the answer but do not provide any additional followup questions.
43+
When dealing with vets, if the user is unsure about the returned results, explain that there may be additional data that was not returned.
44+
Only if the user is asking about the total number of all vets, answer that there are a lot and ask for some additional criteria.
45+
For owners, pets or visits - provide the correct data.
46+
""")
4347
.defaultAdvisors(
4448
// Chat memory helps us keep context when using the chatbot for up to 10 previous messages.
4549
new MessageChatMemoryAdvisor(chatMemory, DEFAULT_CHAT_MEMORY_CONVERSATION_ID, 10), // CHAT MEMORY
@@ -64,7 +68,7 @@ public String exchange(@RequestBody String query) {
6468
.call()
6569
.content();
6670
} catch (Exception exception) {
67-
exception.printStackTrace();
71+
LOG.error("Error processing chat message", exception);
6872
return "Chat is currently unavailable. Please try again later.";
6973
}
7074
}

spring-petclinic-genai-service/src/main/java/org/springframework/samples/petclinic/genai/VectorStoreController.java

+23-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22

33
import java.io.File;
44
import java.io.IOException;
5+
import java.nio.file.Files;
6+
import java.nio.file.attribute.FileAttribute;
7+
import java.nio.file.attribute.PosixFilePermission;
8+
import java.nio.file.attribute.PosixFilePermissions;
59
import java.util.List;
10+
import java.util.Set;
611

12+
import org.apache.commons.lang3.SystemUtils;
713
import org.slf4j.Logger;
814
import org.slf4j.LoggerFactory;
915
import org.springframework.ai.document.Document;
@@ -36,9 +42,8 @@ public class VectorStoreController {
3642

3743
private final VectorStore vectorStore;
3844
private final WebClient webClient;
39-
private final String vetsHostname = "http://vets-service/";
40-
41-
public VectorStoreController(VectorStore vectorStore, WebClient.Builder webClientBuilder) throws IOException {
45+
46+
public VectorStoreController(VectorStore vectorStore, WebClient.Builder webClientBuilder) {
4247
this.webClient = webClientBuilder.build();
4348
this.vectorStore = vectorStore;
4449
}
@@ -61,7 +66,8 @@ public void loadVetDataToVectorStoreOnStartup(ApplicationStartedEvent event) thr
6166
// If vectorstore.json is deleted, the data will be loaded on startup every time.
6267
// Warning - this can be costly in terms of credits used with the AI provider.
6368
// Fetches all Vet entites and creates a document per vet
64-
List<Vet> vets = webClient
69+
String vetsHostname = "http://vets-service/";
70+
List<Vet> vets = webClient
6571
.get()
6672
.uri(vetsHostname + "vets")
6773
.retrieve()
@@ -77,7 +83,18 @@ public void loadVetDataToVectorStoreOnStartup(ApplicationStartedEvent event) thr
7783
this.vectorStore.add(documents);
7884

7985
if (vectorStore instanceof SimpleVectorStore) {
80-
var file = File.createTempFile("vectorstore", ".json");
86+
File file;
87+
if(SystemUtils.IS_OS_UNIX) {
88+
// java:S5443 Sonar rule: Using publicly writable directories is security-sensitive
89+
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
90+
file = Files.createTempFile("vectorstore", ".json", attr).toFile();
91+
}
92+
else {
93+
file= Files.createTempFile("vectorstore", ".json").toFile();
94+
file.setReadable(true, true);
95+
file.setWritable(true, true);
96+
file.setExecutable(true, true);
97+
}
8198
((SimpleVectorStore) this.vectorStore).save(file);
8299
logger.info("vector store contents written to {}", file.getAbsolutePath());
83100
}
@@ -98,7 +115,7 @@ public Resource convertListToJsonResource(List<Vet> vets) {
98115
return new ByteArrayResource(jsonBytes);
99116
}
100117
catch (JsonProcessingException e) {
101-
e.printStackTrace();
118+
logger.error("Error processing JSON in the convertListToJsonResource function", e);
102119
return null;
103120
}
104121
}

0 commit comments

Comments
 (0)