diff --git a/build.gradle b/build.gradle index 4ea0e89f..ee7a203c 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ ext { springBootVersion = '2.6.6' springVersion = '6.0.6' springOauth2Version = "2.5.1.RELEASE" - springDocVersion = '1.6.14' + springDocVersion = '2.2.0' lombokVersion = '1.18.26' junit5Version = '5.9.2' radarSpringAuthVersion = '1.2.0' @@ -68,7 +68,7 @@ dependencies { runtimeOnly("org.hibernate.validator:hibernate-validator:$hibernateValidatorVersion") // Open API spec - implementation(group: 'org.springdoc', name: 'springdoc-openapi-ui', version: springDocVersion) + implementation(group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: springDocVersion) //runtimeOnly('org.springframework.boot:spring-boot-devtools') diff --git a/src/main/java/org/radarbase/appserver/event/state/MessageStateEventListener.java b/src/main/java/org/radarbase/appserver/event/state/MessageStateEventListener.java index 9fee4f0a..b3ccd902 100644 --- a/src/main/java/org/radarbase/appserver/event/state/MessageStateEventListener.java +++ b/src/main/java/org/radarbase/appserver/event/state/MessageStateEventListener.java @@ -23,14 +23,18 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.radarbase.appserver.event.state.dto.DataMessageStateEventDto; import org.radarbase.appserver.event.state.dto.NotificationStateEventDto; import org.radarbase.appserver.service.DataMessageStateEventService; import org.radarbase.appserver.service.NotificationStateEventService; -import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.event.TransactionalEventListener; + +import java.util.Map; @Slf4j @Component @@ -55,7 +59,9 @@ public MessageStateEventListener(ObjectMapper objectMapper, * * @param event the event to respond to */ - @EventListener(value = NotificationStateEventDto.class) + @Transactional(propagation = Propagation.REQUIRES_NEW) + @TransactionalEventListener(classes = NotificationStateEventDto.class) + @Async public void onNotificationStateChange(NotificationStateEventDto event) { String info = convertMapToString(event.getAdditionalInfo()); log.debug("ID: {}, STATE: {}", event.getNotification().getId(), event.getState()); @@ -65,7 +71,9 @@ public void onNotificationStateChange(NotificationStateEventDto event) { notificationStateEventService.addNotificationStateEvent(eventEntity); } - @EventListener(value = DataMessageStateEventDto.class) + @Transactional(propagation = Propagation.REQUIRES_NEW) + @TransactionalEventListener(value = DataMessageStateEventDto.class) + @Async public void onDataMessageStateChange(DataMessageStateEventDto event) { String info = convertMapToString(event.getAdditionalInfo()); log.debug("ID: {}, STATE: {}", event.getDataMessage().getId(), event.getState()); diff --git a/src/main/java/org/radarbase/appserver/event/state/TaskStateEventListener.java b/src/main/java/org/radarbase/appserver/event/state/TaskStateEventListener.java index 7ac1f778..47b7cfc9 100644 --- a/src/main/java/org/radarbase/appserver/event/state/TaskStateEventListener.java +++ b/src/main/java/org/radarbase/appserver/event/state/TaskStateEventListener.java @@ -24,10 +24,15 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.radarbase.appserver.event.state.dto.NotificationStateEventDto; import org.radarbase.appserver.event.state.dto.TaskStateEventDto; import org.radarbase.appserver.service.TaskStateEventService; import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.event.TransactionalEventListener; import java.util.Map; @@ -51,7 +56,9 @@ public TaskStateEventListener(ObjectMapper objectMapper, * * @param event the event to respond to */ - @EventListener(value = TaskStateEventDto.class) + @Transactional(propagation = Propagation.REQUIRES_NEW) + @TransactionalEventListener(classes = TaskStateEventDto.class) + @Async public void onTaskStateChange(TaskStateEventDto event) { String info = convertMapToString(event.getAdditionalInfo()); log.debug("ID: {}, STATE: {}", event.getTask().getId(), event.getState()); diff --git a/src/main/java/org/radarbase/appserver/service/GithubClient.java b/src/main/java/org/radarbase/appserver/service/GithubClient.java index 72b54146..4b88bbd1 100644 --- a/src/main/java/org/radarbase/appserver/service/GithubClient.java +++ b/src/main/java/org/radarbase/appserver/service/GithubClient.java @@ -40,6 +40,10 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; +import java.util.concurrent.Executor; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; @Slf4j @Component @@ -47,12 +51,12 @@ public class GithubClient { private static final String GITHUB_API_URI = "api.github.com"; private static final String GITHUB_API_ACCEPT_HEADER = "application/vnd.github.v3+json"; - private final transient HttpClient client; @Nonnull private final transient String authorizationHeader; private transient final Duration httpTimeout; + private transient final Executor executor; @Value("${security.github.client.maxContentLength:1000000}") private transient int maxContentLength; @@ -64,11 +68,11 @@ public GithubClient( @Value("${security.github.client.token:}") String githubToken) { this.authorizationHeader = githubToken != null ? "Bearer " + githubToken.trim() : ""; this.httpTimeout = Duration.ofSeconds(httpTimeout); - this.client = HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_1_1) - .followRedirects(HttpClient.Redirect.NORMAL) - .connectTimeout(this.httpTimeout) - .build(); + this.executor = new ThreadPoolExecutor(0, + 8, + 30, + TimeUnit.SECONDS, + new SynchronousQueue<>()); } public String getGithubContent(String url) throws IOException, InterruptedException { @@ -94,10 +98,16 @@ public String getGithubContent(String url) throws IOException, InterruptedExcept } private HttpResponse makeRequest(URI uri) throws InterruptedException { + HttpClient client = HttpClient.newBuilder() + .executor(executor) + .version(HttpClient.Version.HTTP_1_1) + .followRedirects(HttpClient.Redirect.NORMAL) + .connectTimeout(this.httpTimeout) + .build(); try { return client.send(getRequest(uri), HttpResponse.BodyHandlers.ofInputStream()); } catch (IOException ex) { - log.error("Failed to retrieve data from github: {}", ex.toString()); + log.error("Failed to retrieve data from github {}: {}", uri, ex.toString()); throw new ResponseStatusException(HttpStatus.BAD_GATEWAY, "Github responded with an error."); } } diff --git a/src/main/java/org/radarbase/appserver/service/TaskService.java b/src/main/java/org/radarbase/appserver/service/TaskService.java index a23432b0..e75a0f56 100644 --- a/src/main/java/org/radarbase/appserver/service/TaskService.java +++ b/src/main/java/org/radarbase/appserver/service/TaskService.java @@ -159,14 +159,16 @@ private void addTaskStateEvent(Task t, TaskState state, Instant time) { @Transactional public Task updateTaskStatus(Task oldTask, TaskState state) { User user = oldTask.getUser(); - if (this.taskRepository.existsByUserIdAndNameAndTimestamp(user.getId(), oldTask.getName(), oldTask.getTimestamp())) { - if (state.equals(TaskState.COMPLETED)) { - oldTask.setCompleted(true); - oldTask.setTimeCompleted(Timestamp.from(Instant.now())); - } - oldTask.setStatus(state); - return this.taskRepository.saveAndFlush(oldTask); - } else throw new NotFoundException( - "The Task does not exists. Please Use add endpoint"); + + if (!this.taskRepository.existsByUserIdAndNameAndTimestamp(user.getId(), oldTask.getName(), oldTask.getTimestamp())) { + throw new NotFoundException("The Task " + oldTask.getId() + " does not exist to set to state " + state + ". Please Use add endpoint"); + } + + if (state.equals(TaskState.COMPLETED)) { + oldTask.setCompleted(true); + oldTask.setTimeCompleted(Timestamp.from(Instant.now())); + } + oldTask.setStatus(state); + return this.taskRepository.saveAndFlush(oldTask); } } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 694c1546..b5e7f81f 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -100,7 +100,7 @@ security.radar.managementportal.url=http://localhost:8081 #security.oauth2.client.userAuthorizationUri= # Github Authentication security.github.client.token= -security.github.client.timeout=PT10s +security.github.client.timeout=10 # max content size 1 MB security.github.client.maxContentLength=1000000 security.github.cache.size=10000