diff --git a/src/main/java/com/olympus/hermione/controllers/ExecutionController.java b/src/main/java/com/olympus/hermione/controllers/ExecutionController.java index 0ba2ebf..6961a44 100644 --- a/src/main/java/com/olympus/hermione/controllers/ExecutionController.java +++ b/src/main/java/com/olympus/hermione/controllers/ExecutionController.java @@ -24,15 +24,4 @@ public class ExecutionController { return scenarioExecutionRepository.findById(id).get(); } - // @PostMapping("/updateRating") - // public String updateScenarioExecRating(@RequestBody ScenarioExecution scenarioExecution){ - // String result = scenarioExecutionService.updateRating2(scenarioExecution); - // return result; - // } - - @GetMapping("/updateRating") - public String updateScenarioExecRating(@RequestParam String id, @RequestParam String rating){ - String result = scenarioExecutionService.updateRating(id, rating); - return result; - } } diff --git a/src/main/java/com/olympus/hermione/controllers/ScenarioController.java b/src/main/java/com/olympus/hermione/controllers/ScenarioController.java index 99c7386..581a62f 100644 --- a/src/main/java/com/olympus/hermione/controllers/ScenarioController.java +++ b/src/main/java/com/olympus/hermione/controllers/ScenarioController.java @@ -1,13 +1,22 @@ package com.olympus.hermione.controllers; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; import java.util.List; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.olympus.hermione.dto.ScenarioExecutionInput; import com.olympus.hermione.dto.ScenarioOutput; import com.olympus.hermione.models.Scenario; @@ -20,6 +29,7 @@ import com.olympus.model.Application; import com.olympus.model.Project; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; @RestController public class ScenarioController { @@ -33,6 +43,7 @@ public class ScenarioController { @Autowired ScenarioService scenarioService; + @GetMapping("/scenarios") public Iterable getScenarios() { return scenarioRepository.findAll(); @@ -90,31 +101,33 @@ public class ScenarioController { return scenarioExecutionService.getExecutionProgress(id); } - @GetMapping("/scenarios/execute/{id}") - public ScenarioExecution getScenarioExecution(@PathVariable String id) { - ScenarioExecution scenarioExecution = scenarioExecutionRepository.findById(id).get(); - String apiKey = scenarioExecution.getScenario().getAiModel().getApiKey(); - String endpoint = scenarioExecution.getScenario().getAiModel().getEndpoint(); - List availableForProject = scenarioExecution.getScenario().getAvailableForProjects(); - List availableForApplication = scenarioExecution.getScenario().getAvailableForApplications(); - if (apiKey != null) { - scenarioExecution.getScenario().getAiModel().setApiKey("**********"); - } - if (endpoint != null) { - scenarioExecution.getScenario().getAiModel().setEndpoint("**********"); - } - if (availableForProject != null) { - scenarioExecution.getScenario().setAvailableForProjects(null); - } - if (availableForApplication != null) { - scenarioExecution.getScenario().setAvailableForApplications(null); - } - return scenarioExecution; - } + @GetMapping("/scenarios/execute/{id}") + public ScenarioExecution getScenarioExecution(@PathVariable String id) { + ScenarioExecution scenarioExecution = scenarioExecutionRepository.findById(id).get(); + String apiKey = scenarioExecution.getScenario().getAiModel().getApiKey(); + String endpoint = scenarioExecution.getScenario().getAiModel().getEndpoint(); + List availableForProject = scenarioExecution.getScenario().getAvailableForProjects(); + List availableForApplication = scenarioExecution.getScenario().getAvailableForApplications(); + if (apiKey != null) { + scenarioExecution.getScenario().getAiModel().setApiKey("**********"); + } + if (endpoint != null) { + scenarioExecution.getScenario().getAiModel().setEndpoint("**********"); + } + if (availableForProject != null) { + scenarioExecution.getScenario().setAvailableForProjects(null); + } + if (availableForApplication != null) { + scenarioExecution.getScenario().setAvailableForApplications(null); + } + return scenarioExecution; +} - @GetMapping("/scenariosByUser") - public List getScenarioByUser() { - return scenarioExecutionService.getListExecutionScenarioByUser(); + @PostMapping("/executions") + public Page getAdvancedExecutions( + @RequestBody Map allParams) { + + return scenarioExecutionService.getFilteredExecutions(allParams); } @GetMapping("/getScenariosForRE") @@ -122,6 +135,10 @@ public class ScenarioController { return scenarioService.getListScenariosForRE(); } - + @GetMapping("/updateRating") + public String updateScenarioExecRating(@RequestParam String id, @RequestParam String rating){ + String result = scenarioService.updateRating(id, rating); + return result; + } } diff --git a/src/main/java/com/olympus/hermione/repository/ScenarioExecutionRepository.java b/src/main/java/com/olympus/hermione/repository/ScenarioExecutionRepository.java index 6c7e3b6..47a1aad 100644 --- a/src/main/java/com/olympus/hermione/repository/ScenarioExecutionRepository.java +++ b/src/main/java/com/olympus/hermione/repository/ScenarioExecutionRepository.java @@ -2,6 +2,8 @@ package com.olympus.hermione.repository; import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; @@ -21,14 +23,31 @@ public interface ScenarioExecutionRepository extends MongoRepository findByExecutedByUserIdAndInputs(String userId, String selectedProject, String selectedApplication); - @Query("{ $and: [ { 'executedByUserId': ?0 }, { 'scenarioExecutionInput.inputs.selected_project': ?1 }, { 'scenarioExecutionInput.inputs.selected_application': ?2 } ] }") - List getFromProjectAndAPP(String userId, String value1, String value2, Sort sort); - //findByExecutedByUserIdAndInputsOrderByStartDateDesc + // @Query("{ $and: [ { 'executedByUserId': ?0 }, { 'scenarioExecutionInput.inputs.selected_project': ?1 }, { 'scenarioExecutionInput.inputs.selected_application': ?2 } ] }") + // List getFromProjectAndAPP(String userId, String value1, String value2, Sort sort); + // //findByExecutedByUserIdAndInputsOrderByStartDateDesc - @Query("{ $and: [ { 'executedByUserId': ?0 }, { 'scenarioExecutionInput.inputs.selected_project': ?1 } ] }") - List getFromProject(String userId, String value1, Sort sort); + @Query("{ $and: [ { 'scenarioExecutionInput.inputs.selected_project': ?0 }, { 'scenarioExecutionInput.inputs.selected_application': ?1 } ] }") + Page getFromProjectAndAPP( String value1, String value2, Pageable pageable); + + @Query("{ $and: [ " + + " { 'scenarioExecutionInput.inputs.selected_project': ?0 }, " + + " { 'scenarioExecutionInput.inputs.selected_application': ?1 }, " + + " { $or: [ { 'scenarioExecutionInput.inputs.optional_field': ?2 }, { 'scenarioExecutionInput.inputs.optional_field': { $exists: false } } ] } " + + "] }") + Page getFromProjectAndAPPOptional( + String value1, + String value2, + String optionalValue, + Pageable pageable); + // @Query("{ $and: [ { 'executedByUserId': ?0 }, { 'scenarioExecutionInput.inputs.selected_project': ?1 } ] }") + // List getFromProject(String userId, String value1, Sort sort); + + @Query("{ $and: [ { 'scenarioExecutionInput.inputs.selected_project': ?0 } ] }") + Page getFromProject( String value1, Pageable pageable); + } diff --git a/src/main/java/com/olympus/hermione/services/ScenarioExecutionService.java b/src/main/java/com/olympus/hermione/services/ScenarioExecutionService.java index 4d25613..fef2f68 100644 --- a/src/main/java/com/olympus/hermione/services/ScenarioExecutionService.java +++ b/src/main/java/com/olympus/hermione/services/ScenarioExecutionService.java @@ -4,14 +4,18 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.file.Files; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.Base64; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.OptionalInt; import java.util.stream.IntStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import org.springframework.data.domain.PageRequest; import org.slf4j.LoggerFactory; import org.springframework.ai.azure.openai.AzureOpenAiChatModel; @@ -29,7 +33,14 @@ import org.springframework.ai.vectorstore.VectorStore; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; import org.springframework.scheduling.annotation.Async; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; @@ -46,6 +57,7 @@ import com.olympus.hermione.repository.ScenarioRepository; import com.olympus.hermione.security.entity.User; import com.olympus.hermione.stepSolvers.AdvancedAIPromptSolver; import com.olympus.hermione.stepSolvers.SummarizeDocSolver; +import com.olympus.hermione.stepSolvers.TestExternalCodeGenieSolver; import com.olympus.hermione.stepSolvers.BasicAIPromptSolver; import com.olympus.hermione.stepSolvers.BasicQueryRagSolver; import com.olympus.hermione.stepSolvers.DeleteDocTempSolver; @@ -54,6 +66,7 @@ import com.olympus.hermione.stepSolvers.QueryNeo4JSolver; import com.olympus.hermione.stepSolvers.SourceCodeRagSolver; import com.olympus.hermione.stepSolvers.StepSolver; +import org.bson.types.ObjectId; import org.neo4j.driver.Driver; import org.slf4j.Logger; @@ -64,18 +77,18 @@ import com.olympus.hermione.stepSolvers.ExternalAgentSolver; import com.olympus.hermione.stepSolvers.ExternalCodeGenieSolver; import com.olympus.hermione.stepSolvers.OlynmpusChatClientSolver; - - - @Service public class ScenarioExecutionService { @Value("${file.upload-dir}") private String uploadDir; - + + @Autowired + private MongoTemplate mongoTemplate; + @Autowired private ScenarioRepository scenarioRepository; - + @Autowired private ScenarioExecutionRepository scenarioExecutionRepository; @@ -84,10 +97,9 @@ public class ScenarioExecutionService { @Autowired VectorStore vectorStore; - - @Autowired - DiscoveryClient discoveryClient; + @Autowired + DiscoveryClient discoveryClient; @Autowired Driver graphDriver; @@ -100,44 +112,49 @@ public class ScenarioExecutionService { private Logger logger = LoggerFactory.getLogger(ScenarioExecutionService.class); - public ScenarioOutput getExecutionProgress(String scenarioExecutionId){ + public ScenarioOutput getExecutionProgress(String scenarioExecutionId) { ScenarioOutput scenarioOutput = new ScenarioOutput(); - Optional o_scenarioExecution = scenarioExecutionRepository.findById(scenarioExecutionId); - - if(o_scenarioExecution.isPresent()){ + Optional o_scenarioExecution = scenarioExecutionRepository.findById(scenarioExecutionId); + + if (o_scenarioExecution.isPresent()) { ScenarioExecution scenarioExecution = o_scenarioExecution.get(); scenarioExecution.setCurrentStepId(scenarioExecution.getCurrentStepId()); - if(scenarioExecution.getExecSharedMap()!=null && scenarioExecution.getExecSharedMap().get("scenario_output")!=null){ + if (scenarioExecution.getExecSharedMap() != null + && scenarioExecution.getExecSharedMap().get("scenario_output") != null) { scenarioOutput.setScenarioExecution_id(scenarioExecution.getId()); scenarioOutput.setStatus("OK"); scenarioOutput.setStringOutput(scenarioExecution.getExecSharedMap().get("scenario_output").toString()); scenarioOutput.setMessage(""); - }else{ + } else { scenarioOutput.setScenarioExecution_id(scenarioExecution.getId()); scenarioOutput.setStatus("IN_PROGRESS"); - if (scenarioExecution.getCurrentStepId() != null){ + if (scenarioExecution.getCurrentStepId() != null) { OptionalInt indexOpt = IntStream.range(0, scenarioExecution.getScenario().getSteps().size()) - .filter(i -> scenarioExecution.getScenario().getSteps().get(i).getStepId().equals(scenarioExecution.getCurrentStepId())) - .map(i -> i + 1) - .findFirst(); + .filter(i -> scenarioExecution.getScenario().getSteps().get(i).getStepId() + .equals(scenarioExecution.getCurrentStepId())) + .map(i -> i + 1) + .findFirst(); scenarioOutput.setCurrentStepId(scenarioExecution.getCurrentStepId()); scenarioOutput.setCurrentStepDescription(scenarioExecution.getCurrentStepDescription()); - scenarioOutput.setMessage("Executing step "+indexOpt.getAsInt()+"/"+scenarioExecution.getScenario().getSteps().size()+": "+scenarioOutput.getCurrentStepDescription()+"."); - }else { + scenarioOutput.setMessage("Executing step " + indexOpt.getAsInt() + "/" + + scenarioExecution.getScenario().getSteps().size() + ": " + + scenarioOutput.getCurrentStepDescription() + "."); + } else { scenarioOutput.setMessage("Starting execution..."); } } - - if(scenarioExecution.getLatestStepStatus()!= null && scenarioExecution.getLatestStepStatus().equals("ERROR")){ + + if (scenarioExecution.getLatestStepStatus() != null + && scenarioExecution.getLatestStepStatus().equals("ERROR")) { scenarioOutput.setScenarioExecution_id(scenarioExecution.getId()); scenarioOutput.setStatus("ERROR"); scenarioOutput.setMessage(scenarioExecution.getLatestStepOutput()); } - - }else{ + + } else { scenarioOutput.setScenarioExecution_id(null); scenarioOutput.setStatus("ERROR"); scenarioOutput.setMessage("Scenario Execution not found"); @@ -147,16 +164,16 @@ public class ScenarioExecutionService { } @Async - public void executeScenarioAsync(ScenarioOutput scenarioOutput){ + public void executeScenarioAsync(ScenarioOutput scenarioOutput) { String scenarioExecutionID = scenarioOutput.getScenarioExecution_id(); - Optional o_scenarioExecution = scenarioExecutionRepository.findById(scenarioExecutionID); + Optional o_scenarioExecution = scenarioExecutionRepository.findById(scenarioExecutionID); - if(o_scenarioExecution.isPresent()){ + if (o_scenarioExecution.isPresent()) { ScenarioExecution scenarioExecution = o_scenarioExecution.get(); - HashMap inputs = scenarioExecution.getScenarioExecutionInput().getInputs(); - Optional o_scenario = scenarioRepository.findById(scenarioExecution.getScenario().getId()); + HashMap inputs = scenarioExecution.getScenarioExecutionInput().getInputs(); + Optional o_scenario = scenarioRepository.findById(scenarioExecution.getScenario().getId()); Scenario scenario = o_scenario.get(); @@ -166,81 +183,76 @@ public class ScenarioExecutionService { HashMap execSharedMap = new HashMap(); execSharedMap.put("user_input", inputs); scenarioExecution.setExecSharedMap(execSharedMap); - + AiModel aiModel; - if(scenario.getAiModel() != null){ - aiModel = scenario.getAiModel(); - }else { + if (scenario.getAiModel() != null) { + aiModel = scenario.getAiModel(); + } else { aiModel = aiModelRepository.findByIsDefault(true); scenario.setAiModel(aiModel); scenarioExecution.setScenario(scenario); } - - ChatModel chatModel = createChatModel(aiModel); - + + ChatModel chatModel = createChatModel(aiModel); + scenarioExecutionRepository.save(scenarioExecution); - - if(scenario.isUseChatMemory()){ + if (scenario.isUseChatMemory()) { logger.info("Initializing chatClient with chat-memory advisor"); ChatMemory chatMemory = new InMemoryChatMemory(); chatClient = ChatClient.builder(chatModel) - .defaultAdvisors( - new MessageChatMemoryAdvisor(chatMemory), // chat-memory advisor - new SimpleLoggerAdvisor() - ) - .build(); + .defaultAdvisors( + new MessageChatMemoryAdvisor(chatMemory), // chat-memory advisor + new SimpleLoggerAdvisor()) + .build(); - }else{ + } else { logger.info("Initializing chatClient with simple logger advisor"); chatClient = ChatClient.builder(chatModel) - .defaultAdvisors( - new SimpleLoggerAdvisor() - ) - .build(); + .defaultAdvisors( + new SimpleLoggerAdvisor()) + .build(); } - List steps = scenario.getSteps(); - String startStepId=scenario.getStartWithStepId(); + String startStepId = scenario.getStartWithStepId(); + + ScenarioStep startStep = steps.stream().filter(step -> step.getStepId().equals(startStepId)).findFirst() + .orElse(null); - ScenarioStep startStep = steps.stream().filter(step -> step.getStepId().equals(startStepId)).findFirst().orElse(null); - executeScenarioStep(startStep, scenarioExecution); Integer usedTokens = (scenarioExecution.getUsedTokens() != null) ? scenarioExecution.getUsedTokens() : 0; - while (scenarioExecution.getNextStepId()!=null) { - ScenarioStep step = steps.stream().filter(s -> s.getStepId().equals(scenarioExecution.getNextStepId())).findFirst().orElse(null); + while (scenarioExecution.getNextStepId() != null) { + ScenarioStep step = steps.stream().filter(s -> s.getStepId().equals(scenarioExecution.getNextStepId())) + .findFirst().orElse(null); executeScenarioStep(step, scenarioExecution); if (scenarioExecution.getUsedTokens() != null && scenarioExecution.getUsedTokens() != 0) { usedTokens += scenarioExecution.getUsedTokens(); - scenarioExecution.setUsedTokens(0); //resetting value for next step if is not an AI step + scenarioExecution.setUsedTokens(0); // resetting value for next step if is not an AI step } - if(scenarioExecution.getLatestStepStatus() != null && scenarioExecution.getLatestStepStatus().equals("ERROR")){ + if (scenarioExecution.getLatestStepStatus() != null + && scenarioExecution.getLatestStepStatus().equals("ERROR")) { logger.error("Error while executing step: " + step.getStepId()); break; } } - + scenarioExecution.setUsedTokens(usedTokens); scenarioExecution.setEndDate(new java.util.Date()); scenarioExecutionRepository.save(scenarioExecution); } } - - - - - private void executeScenarioStep(ScenarioStep step, ScenarioExecution scenarioExecution){ + private void executeScenarioStep(ScenarioStep step, ScenarioExecution scenarioExecution) { logger.info("Start working on step: " + step.getName() + " with type: " + step.getType()); - StepSolver solver=new StepSolver(); - switch (step.getType()) { + StepSolver solver = new StepSolver(); + switch (step.getType()) { case "ADVANCED_QUERY_AI": solver = new AdvancedAIPromptSolver(); break; @@ -278,88 +290,86 @@ public class ScenarioExecutionService { break; } - logger.info("Initializing step: " + step.getStepId()); logger.info("Solving step: " + step.getStepId()); scenarioExecution.setCurrentStepId(step.getStepId()); scenarioExecution.setCurrentStepDescription(step.getName()); - ScenarioExecution scenarioExecutionNew=scenarioExecution; + ScenarioExecution scenarioExecutionNew = scenarioExecution; - try{ + try { solver.init(step, scenarioExecution, - vectorStore,chatModel,chatClient,graphDriver,neo4JUitilityService - ,discoveryClient); + vectorStore, chatModel, chatClient, graphDriver, neo4JUitilityService, discoveryClient); scenarioExecutionNew = solver.solveStep(); logger.info("Step solved: " + step.getStepId()); logger.info("Next step: " + scenarioExecutionNew.getNextStepId()); - }catch (Exception e){ + } catch (Exception e) { logger.error("Error while solving step: " + step.getStepId() + " => " + e.getMessage()); scenarioExecutionNew.setNextStepId(null); scenarioExecutionNew.setLatestStepStatus("ERROR"); scenarioExecutionNew.setLatestStepOutput(e.getMessage()); } - scenarioExecutionRepository.save(scenarioExecutionNew); } - - public ScenarioOutput prepareScrenarioExecution(ScenarioExecutionInput scenarioExecutionInput){ + public ScenarioOutput prepareScrenarioExecution(ScenarioExecutionInput scenarioExecutionInput) { String scenarioId = scenarioExecutionInput.getScenario_id(); ScenarioOutput scenarioOutput = new ScenarioOutput(); - Optional o_scenario = scenarioRepository.findById(scenarioId); + Optional o_scenario = scenarioRepository.findById(scenarioId); - if(o_scenario.isPresent()){ + if (o_scenario.isPresent()) { Scenario scenario = o_scenario.get(); logger.info("Executing scenario: " + scenario.getName()); - + String folder_name = ""; ScenarioExecution scenarioExecution = new ScenarioExecution(); scenarioExecution.setScenario(scenario); - //prendi i file dalla cartella temporanea se è presente una chiave con name "MultiFileUpload" - if(scenarioExecutionInput.getInputs().containsKey("MultiFileUpload")){ + // prendi i file dalla cartella temporanea se è presente una chiave con name + // "MultiFileUpload" + if (scenarioExecutionInput.getInputs().containsKey("MultiFileUpload")) { folder_name = scenarioExecutionInput.getInputs().get("MultiFileUpload"); - if(folder_name!=null && !folder_name.equals("")){ - try{ + if (folder_name != null && !folder_name.equals("")) { + try { String base64 = folderToBase64(folder_name); scenarioExecutionInput.getInputs().put("MultiFileUpload", base64); - }catch(Exception e){ + } catch (Exception e) { logger.error("Error while converting folder to base64: " + e.getMessage()); } } } - if(scenarioExecutionInput.getInputs().containsKey("SingleFileUpload")){ - scenarioExecutionInput.getInputs().put("SingleFileUpload", uploadDir + folder_name + "/" + scenarioExecutionInput.getInputs().get("SingleFileUpload")); + if (scenarioExecutionInput.getInputs().containsKey("SingleFileUpload")) { + scenarioExecutionInput.getInputs().put("SingleFileUpload", + uploadDir + folder_name + "/" + scenarioExecutionInput.getInputs().get("SingleFileUpload")); } scenarioExecution.setScenarioExecutionInput(scenarioExecutionInput); - try{ - if( SecurityContextHolder.getContext() != null - && SecurityContextHolder.getContext().getAuthentication() != null - && SecurityContextHolder.getContext().getAuthentication().getPrincipal()!= null - ){ - + try { + if (SecurityContextHolder.getContext() != null + && SecurityContextHolder.getContext().getAuthentication() != null + && SecurityContextHolder.getContext().getAuthentication().getPrincipal() != null) { + User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); scenarioExecution.setExecutedByUserId(principal.getId().toString()); scenarioExecution.setExecutedByUsername(principal.getUsername()); - if(principal.getSelectedApplication()!=null){ - scenarioExecutionInput.getInputs().put("selected_application", principal.getSelectedApplication().getInternal_name()); + if (principal.getSelectedApplication() != null) { + scenarioExecutionInput.getInputs().put("selected_application", + principal.getSelectedApplication().getInternal_name()); } - scenarioExecutionInput.getInputs().put("selected_project", principal.getSelectedProject().getInternal_name()); + scenarioExecutionInput.getInputs().put("selected_project", + principal.getSelectedProject().getInternal_name()); } - }catch(Exception e){ + } catch (Exception e) { logger.error("Error while saving user information in scenario execution: " + e.getMessage()); } - scenarioExecutionRepository.save(scenarioExecution); @@ -371,7 +381,7 @@ public class ScenarioExecutionService { return scenarioOutput; } - public String folderToBase64(String folderName) throws Exception { + public String folderToBase64(String folderName) throws Exception { File folder = new File(uploadDir, folderName); if (!folder.exists() || !folder.isDirectory()) { throw new IllegalArgumentException("La cartella specificata non esiste o non è una directory"); @@ -381,7 +391,7 @@ public class ScenarioExecutionService { File zipFile = File.createTempFile("folder", ".zip"); try (FileOutputStream fos = new FileOutputStream(zipFile); - ZipOutputStream zos = new ZipOutputStream(fos)) { + ZipOutputStream zos = new ZipOutputStream(fos)) { zipFolder(folder, folder.getName(), zos); } @@ -421,107 +431,257 @@ public class ScenarioExecutionService { } } - - private ChatModel createChatModel(AiModel aiModel){ - switch(aiModel.getApiProvider()){ + private ChatModel createChatModel(AiModel aiModel) { + switch (aiModel.getApiProvider()) { case "AzureOpenAI": - OpenAIClientBuilder openAIClient = new OpenAIClientBuilder() - .credential(new AzureKeyCredential(aiModel.getApiKey())) - .endpoint(aiModel.getEndpoint()); - + OpenAIClientBuilder openAIClient = new OpenAIClientBuilder() + .credential(new AzureKeyCredential(aiModel.getApiKey())) + .endpoint(aiModel.getEndpoint()); AzureOpenAiChatOptions openAIChatOptions = AzureOpenAiChatOptions.builder() - .deploymentName(aiModel.getModel()) - .maxTokens(aiModel.getMaxTokens()) - .temperature(Double.valueOf(aiModel.getTemperature())) - .build(); - + .deploymentName(aiModel.getModel()) + .maxTokens(aiModel.getMaxTokens()) + .temperature(Double.valueOf(aiModel.getTemperature())) + .build(); + AzureOpenAiChatModel azureOpenaichatModel = new AzureOpenAiChatModel(openAIClient, openAIChatOptions); logger.info("AI model used: " + aiModel.getModel()); return azureOpenaichatModel; - - case "OpenAI": OpenAiApi openAiApi = new OpenAiApi(aiModel.getApiKey()); OpenAiChatOptions openAiChatOptions = OpenAiChatOptions.builder() - .model(aiModel.getModel()) - .temperature(Double.valueOf(aiModel.getTemperature())) - .maxTokens(aiModel.getMaxTokens()) - .build(); - - OpenAiChatModel openaichatModel = new OpenAiChatModel(openAiApi,openAiChatOptions); - logger.info("AI model used: " + aiModel.getModel()); - return openaichatModel; + .model(aiModel.getModel()) + .temperature(Double.valueOf(aiModel.getTemperature())) + .maxTokens(aiModel.getMaxTokens()) + .build(); + OpenAiChatModel openaichatModel = new OpenAiChatModel(openAiApi, openAiChatOptions); + logger.info("AI model used: " + aiModel.getModel()); + return openaichatModel; case "GoogleGemini": - OpenAIClientBuilder openAIClient2 = new OpenAIClientBuilder() + OpenAIClientBuilder openAIClient2 = new OpenAIClientBuilder() .credential(new AzureKeyCredential(aiModel.getApiKey())) .endpoint(aiModel.getEndpoint()); - - AzureOpenAiChatOptions openAIChatOptions2 = AzureOpenAiChatOptions.builder() - .deploymentName(aiModel.getModel()) + AzureOpenAiChatOptions openAIChatOptions2 = AzureOpenAiChatOptions.builder() + .deploymentName(aiModel.getModel()) .maxTokens(aiModel.getMaxTokens()) .temperature(Double.valueOf(aiModel.getTemperature())) .build(); - AzureOpenAiChatModel azureOpenaichatModel2 = new AzureOpenAiChatModel(openAIClient2, openAIChatOptions2); + AzureOpenAiChatModel azureOpenaichatModel2 = new AzureOpenAiChatModel(openAIClient2, + openAIChatOptions2); - logger.info("AI model used : " + aiModel.getModel()); - return azureOpenaichatModel2; + logger.info("AI model used : " + aiModel.getModel()); + return azureOpenaichatModel2; default: throw new IllegalArgumentException("Unsupported AI model: " + aiModel.getName()); } } - public List getListExecutionScenarioByUser(){ - logger.info("getListProjectByUser function:"); + /* + * public List getListExecutionScenario(){ + * logger.info("getListProjectByUser function:"); + * + * List lstScenarioExecution = null; + * + * User principal = (User) + * SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + * + * if(principal.getSelectedApplication()!=null){ + * lstScenarioExecution = + * scenarioExecutionRepository.getFromProjectAndAPP(principal.getId(), + * principal.getSelectedProject().getInternal_name(), + * principal.getSelectedApplication().getInternal_name(), + * Sort.by(Sort.Direction.DESC, "startDate")); + * + * }else{ + * lstScenarioExecution = + * scenarioExecutionRepository.getFromProject(principal.getId(), + * principal.getSelectedProject().getInternal_name(), + * Sort.by(Sort.Direction.DESC, "startDate")); + * } + * + * return lstScenarioExecution; + * + * } + */ - List lstScenarioExecution = null; + public Page getListExecutionScenarioOptional(int page, int size, String scenarioName, + String executedBy, LocalDate startDate) { + logger.info("getListExecutionScenarioOptional function:"); + + List criteriaList = new ArrayList<>(); + User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + // Filtro per progetto selezionato + if (principal.getSelectedProject() != null && principal.getSelectedProject().getId() != null) { + criteriaList.add(Criteria.where("scenarioExecutionInput.inputs.selected_project") + .is(principal.getSelectedProject().getInternal_name())); + } + + // Filtro per applicazione selezionata + if (principal.getSelectedApplication() != null && principal.getSelectedApplication().getId() != null) { + criteriaList.add(Criteria.where("scenarioExecutionInput.inputs.selected_application") + .is(principal.getSelectedApplication().getInternal_name())); + } + + // Filtro per nome scenario + if (scenarioName != null) { + criteriaList.add(Criteria.where("scenarioExecutionInput.scenario.name").is(scenarioName)); + } + + // Filtro per utente che ha eseguito + if (executedBy != null) { + criteriaList.add(Criteria.where("executedByUsername").is(executedBy)); + } + + // Filtro per data di inizio + if (startDate != null) { + criteriaList.add(Criteria.where("startDate").gte(startDate)); + } + + // Costruisce la query solo con i criteri presenti + Criteria criteria = new Criteria(); + if (!criteriaList.isEmpty()) { + criteria = new Criteria().andOperator(criteriaList.toArray(new Criteria[0])); + } + + Query query = new Query(criteria); + long count = mongoTemplate.count(query, ScenarioExecution.class); // Conta i documenti senza paginazione + + // Applica la paginazione solo per ottenere i risultati + Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "startDate")); + query.with(pageable); + + List results = mongoTemplate.find(query, ScenarioExecution.class); + + return new PageImpl<>(results, pageable, count); + } + + public Page getFilteredExecutions(Map filters) { + logger.info("getFilteredExecutions function:"); + + List criteriaList = new ArrayList<>(); + + int page = 0; + int size = 10; + String sortField = "startDate"; + int sortOrder = -1; User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - - if(principal.getSelectedApplication()!=null){ - lstScenarioExecution = scenarioExecutionRepository.getFromProjectAndAPP(principal.getId(), principal.getSelectedProject().getInternal_name(), principal.getSelectedApplication().getInternal_name(), Sort.by(Sort.Direction.DESC, "startDate")); - - }else{ - lstScenarioExecution = scenarioExecutionRepository.getFromProject(principal.getId(), principal.getSelectedProject().getInternal_name(), Sort.by(Sort.Direction.DESC, "startDate")); - } + criteriaList.add(Criteria.where("execSharedMap.user_input.selected_project") + .is(principal.getSelectedProject().getInternal_name())); + criteriaList.add(Criteria.where("execSharedMap.user_input.selected_application") + .is(principal.getSelectedApplication().getInternal_name())); + // here: + // filtri + // here: + // here: vedi perchè non funziona link di view + // here: da sistemare filtro data a backend e i vari equals + // here: add ordinamento - return lstScenarioExecution; + for (Map.Entry entry : filters.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); - } + if ("page".equals(key)) { + page = (int) value; + } else if ("size".equals(key)) { + size = (int) value; + }else if ("sortField".equals(key)) { + if(value!=null) { + sortField = (String) value; + } - public String updateRating2(ScenarioExecution scenaExec){ - logger.info("updateRating function:"); - String result = "KO"; - try{ - scenarioExecutionRepository.save(scenaExec); - result = "OK"; - }catch(Exception e){ - logger.error("Exception in updateRating: {}", e.getMessage()); - } + }else if("sortOrder".equals(key)){ + if(value!=null) { + sortOrder = (int) value; + } + }else if (value instanceof Map) { + Map valueMap = (Map) value; + String operator = (String) valueMap.get("operator"); + List> constraints = (List>) valueMap.get("constraints"); - return result; + for (Map constraint : constraints) { + Object constraintValue = constraint.get("value"); + String matchMode = (String) constraint.get("matchMode"); - } + if (constraintValue != null && !constraintValue.toString().isEmpty()) { + switch (matchMode) { + case "contains": + if (key.equals("_id")) { + criteriaList.add(Criteria.where("_id").is(new ObjectId((String) constraintValue))); + } else { + criteriaList.add(Criteria.where(key).regex((String) constraintValue, "i")); + } + break; + case "notContains": + criteriaList.add(Criteria.where(key).not().regex((String) constraintValue, "i")); + break; + case "dateIs": + criteriaList.add(Criteria.where(key).is( + LocalDate.parse(((String) constraintValue).substring(0, 10)))); - public String updateRating(String id, String rating){ - logger.info("updateRating function:"); - String result = "KO"; - try{ - Optional o_scenarioExecution = scenarioExecutionRepository.findById(id); - if(o_scenarioExecution.isPresent()){ - o_scenarioExecution.get().setRating(rating); - scenarioExecutionRepository.save(o_scenarioExecution.get()); - result = "OK"; + break; + case "dateIsNot": + criteriaList.add(Criteria.where(key).ne(Criteria.where(key).is( + LocalDate.parse(((String) constraintValue).substring(0, 10))))); + break; + case "dateBefore": + criteriaList.add(Criteria.where(key).lt(Criteria.where(key).is( + LocalDate.parse(((String) constraintValue).substring(0, 10))))); + break; + case "dateAfter": + criteriaList.add(Criteria.where(key).gt(Criteria.where(key).is( + LocalDate.parse(((String) constraintValue).substring(0, 10))))); + break; + case "equals": + criteriaList.add(Criteria.where(key).is(constraintValue)); + break; + case "notEquals": + criteriaList.add(Criteria.where(key).ne(constraintValue)); + break; + case "startsWith": + criteriaList.add(Criteria.where(key).regex("^" + constraintValue, "i")); + break; + case "endsWith": + criteriaList.add(Criteria.where(key).regex(constraintValue + "$", "i")); + break; + default: + criteriaList.add(Criteria.where(key).is(constraintValue)); + break; + } + } + } + } else if (value instanceof String) { + criteriaList.add(Criteria.where(key).regex((String) value, "i")); } - }catch(Exception e){ - logger.error("Exception in updateRating: {}", e.getMessage()); } - return result; + + Criteria criteria = new Criteria(); + if (!criteriaList.isEmpty()) { + criteria = new Criteria().andOperator(criteriaList.toArray(new Criteria[0])); + } + + Query query = new Query(criteria); + long count = mongoTemplate.count(query, ScenarioExecution.class); + + Pageable pageable = null; + if(sortOrder == -1) { + pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, sortField)); + }else { + pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, sortField)); + } + query.with(pageable); + + List results = mongoTemplate.find(query, ScenarioExecution.class); + + return new PageImpl<>(results, pageable, count); } + + } diff --git a/src/main/java/com/olympus/hermione/services/ScenarioService.java b/src/main/java/com/olympus/hermione/services/ScenarioService.java index d3de12e..6f71acc 100644 --- a/src/main/java/com/olympus/hermione/services/ScenarioService.java +++ b/src/main/java/com/olympus/hermione/services/ScenarioService.java @@ -7,13 +7,17 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import com.olympus.hermione.models.Scenario; +import com.olympus.hermione.models.ScenarioExecution; import com.olympus.hermione.repository.ProjectRepository; +import com.olympus.hermione.repository.ScenarioExecutionRepository; import com.olympus.hermione.repository.ScenarioRepository; import com.olympus.hermione.security.entity.User; import com.olympus.model.Project; import java.util.ArrayList; import java.util.List; +import java.util.Optional; + import org.bson.types.ObjectId; @Service @@ -24,6 +28,9 @@ public class ScenarioService { @Autowired private ScenarioRepository scenarioRepo; + @Autowired + private ScenarioExecutionRepository scenarioExecutionRepository; + public List getListScenariosByProject(String project){ logger.info("getListProjectByUser function:"); List lstScenarios = null; @@ -117,4 +124,20 @@ public class ScenarioService { return lstScenarios; } + + public String updateRating(String id, String rating) { + logger.info("updateRating function:"); + String result = "KO"; + try { + Optional o_scenarioExecution = scenarioExecutionRepository.findById(id); + if (o_scenarioExecution.isPresent()) { + o_scenarioExecution.get().setRating(rating); + scenarioExecutionRepository.save(o_scenarioExecution.get()); + result = "OK"; + } + } catch (Exception e) { + logger.error("Exception in updateRating: {}", e.getMessage()); + } + return result; + } }