diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml index ae93bec5..56118b4d 100644 --- a/.github/workflows/on_pull_request.yml +++ b/.github/workflows/on_pull_request.yml @@ -13,7 +13,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - uses: DeLaGuardo/setup-graalvm@4.0 with: - graalvm: '21.3.0' + graalvm: '21.1.0' java: 'java11' - name: Install Native Image run: gu install native-image diff --git a/.github/workflows/on_push_master.yml b/.github/workflows/on_push_master.yml index 75cd3dea..84eff484 100644 --- a/.github/workflows/on_push_master.yml +++ b/.github/workflows/on_push_master.yml @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - uses: DeLaGuardo/setup-graalvm@4.0 with: - graalvm: '21.3.0' + graalvm: '21.1.0' java: 'java11' - name: Install Native Image run: gu install native-image @@ -60,7 +60,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - uses: DeLaGuardo/setup-graalvm@4.0 with: - graalvm: '21.3.0' + graalvm: '20.3.2' java: 'java11' - name: Install Native Image run: ${{ env.JAVA_HOME }}\bin\gu.cmd install native-image diff --git a/.github/workflows/on_push_tag.yml b/.github/workflows/on_push_tag.yml index 25a8e2ba..088be9b8 100644 --- a/.github/workflows/on_push_tag.yml +++ b/.github/workflows/on_push_tag.yml @@ -18,7 +18,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - uses: DeLaGuardo/setup-graalvm@4.0 with: - graalvm: '21.3.0' + graalvm: '21.1.0' java: 'java11' - name: Install Native Image run: gu install native-image @@ -62,7 +62,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - uses: DeLaGuardo/setup-graalvm@4.0 with: - graalvm: '21.3.0' + graalvm: '20.3.2' java: 'java11' - name: Install Native Image run: ${{ env.JAVA_HOME }}\bin\gu.cmd install native-image diff --git a/api/build.gradle b/api/build.gradle index e7eabc24..4a200238 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -21,18 +21,14 @@ micronaut { dependencies { compileOnly 'org.projectlombok:lombok:1.18.20' - compileOnly("com.google.code.findbugs:jsr305") - annotationProcessor 'org.projectlombok:lombok:1.18.20' annotationProcessor("io.micronaut.openapi:micronaut-openapi") annotationProcessor("io.micronaut:micronaut-management") annotationProcessor("io.micronaut.security:micronaut-security-annotations") annotationProcessor("io.swagger.core.v3:swagger-annotations") - annotationProcessor("io.micronaut:micronaut-http-validation") implementation("io.micronaut:micronaut-validation") implementation("io.micronaut:micronaut-runtime") - implementation("io.micronaut.rxjava3:micronaut-rxjava3") implementation("javax.annotation:javax.annotation-api") implementation("io.micronaut:micronaut-http-client") implementation("io.micronaut.openapi:micronaut-openapi") @@ -47,7 +43,7 @@ dependencies { testAnnotationProcessor 'org.projectlombok:lombok:1.18.20' testCompileOnly 'org.projectlombok:lombok:1.18.16' - testImplementation("io.micronaut.rxjava3:micronaut-rxjava3-http-client:2.0.0") + testImplementation 'org.testcontainers:kafka:1.15.3' testImplementation "org.testcontainers:junit-jupiter" testImplementation 'org.mockito:mockito-inline:3.7.7' diff --git a/api/src/main/java/com/michelin/ns4kafka/Application.java b/api/src/main/java/com/michelin/ns4kafka/Application.java index 1d923fb1..eaed6e80 100644 --- a/api/src/main/java/com/michelin/ns4kafka/Application.java +++ b/api/src/main/java/com/michelin/ns4kafka/Application.java @@ -2,6 +2,7 @@ import io.micronaut.openapi.annotation.OpenAPIInclude; import io.micronaut.runtime.Micronaut; +import io.reactivex.plugins.RxJavaPlugins; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; @@ -29,6 +30,7 @@ public class Application { public static void main(String[] args) { + RxJavaPlugins.setErrorHandler(throwable -> {}); Micronaut.run(Application.class, args); } } diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/AccessControlListController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/AccessControlListController.java index a5b59d30..e0f54260 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/AccessControlListController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/AccessControlListController.java @@ -12,7 +12,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Comparator; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/AkhqClaimProviderController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/AkhqClaimProviderController.java index 4c530c63..bb3eaf1b 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/AkhqClaimProviderController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/AkhqClaimProviderController.java @@ -12,7 +12,7 @@ import lombok.Getter; import javax.annotation.security.RolesAllowed; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.util.List; import java.util.Map; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/ConnectController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/ConnectController.java index 39c42f4f..9cd2d1ed 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/ConnectController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/ConnectController.java @@ -11,7 +11,7 @@ import io.micronaut.scheduling.annotation.ExecuteOn; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/ConsumerGroupController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/ConsumerGroupController.java index 351a62be..dc1070aa 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/ConsumerGroupController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/ConsumerGroupController.java @@ -11,7 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.kafka.common.TopicPartition; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/NamespaceController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/NamespaceController.java index 349b27b0..81fb24d2 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/NamespaceController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/NamespaceController.java @@ -8,7 +8,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import javax.annotation.security.RolesAllowed; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.ArrayList; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/NamespacedResourceController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/NamespacedResourceController.java index c0bf0598..9b8faecd 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/NamespacedResourceController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/NamespacedResourceController.java @@ -3,7 +3,7 @@ import com.michelin.ns4kafka.models.Namespace; import com.michelin.ns4kafka.services.NamespaceService; -import jakarta.inject.Inject; +import javax.inject.Inject; /** * Base Controller for all Namespaced resources diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/ResourceController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/ResourceController.java index 08fcdf22..8dd1f3d4 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/ResourceController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/ResourceController.java @@ -7,7 +7,7 @@ import io.micronaut.http.HttpResponse; import io.micronaut.security.utils.SecurityService; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/RoleBindingController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/RoleBindingController.java index 6440e2e9..29723aee 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/RoleBindingController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/RoleBindingController.java @@ -11,7 +11,7 @@ import io.micronaut.scheduling.annotation.ExecuteOn; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/StreamController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/StreamController.java index 4f60ccdf..92c83c98 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/StreamController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/StreamController.java @@ -8,7 +8,7 @@ import io.micronaut.http.annotation.*; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/controllers/TopicController.java b/api/src/main/java/com/michelin/ns4kafka/controllers/TopicController.java index c3889765..ea018494 100644 --- a/api/src/main/java/com/michelin/ns4kafka/controllers/TopicController.java +++ b/api/src/main/java/com/michelin/ns4kafka/controllers/TopicController.java @@ -11,7 +11,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.kafka.common.TopicPartition; -import jakarta.inject.Inject; +import javax.inject.Inject; import javax.validation.Valid; import java.time.Instant; import java.util.Date; diff --git a/api/src/main/java/com/michelin/ns4kafka/logs/ConsoleLogListener.java b/api/src/main/java/com/michelin/ns4kafka/logs/ConsoleLogListener.java index e8a058b2..fa516b7f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/logs/ConsoleLogListener.java +++ b/api/src/main/java/com/michelin/ns4kafka/logs/ConsoleLogListener.java @@ -6,7 +6,7 @@ import io.micronaut.core.util.StringUtils; import lombok.extern.slf4j.Slf4j; -import jakarta.inject.Singleton; +import javax.inject.Singleton; @Slf4j @Singleton diff --git a/api/src/main/java/com/michelin/ns4kafka/logs/KafkaLogListener.java b/api/src/main/java/com/michelin/ns4kafka/logs/KafkaLogListener.java index 00ac6432..af706d75 100644 --- a/api/src/main/java/com/michelin/ns4kafka/logs/KafkaLogListener.java +++ b/api/src/main/java/com/michelin/ns4kafka/logs/KafkaLogListener.java @@ -9,8 +9,8 @@ import io.micronaut.core.util.StringUtils; import io.micronaut.scheduling.annotation.Async; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; @Singleton @Requires(property = "ns4kafka.log.kafka.enabled", value = StringUtils.TRUE) diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/DelayStartupListener.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/DelayStartupListener.java index 5eb39bc2..7c431873 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/DelayStartupListener.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/DelayStartupListener.java @@ -6,7 +6,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.List; @Slf4j diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaAccessControlEntryRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaAccessControlEntryRepository.java index 00d5acf4..c495a700 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaAccessControlEntryRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaAccessControlEntryRepository.java @@ -7,7 +7,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.Collection; import java.util.Optional; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaConnectorRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaConnectorRepository.java index 9977b3b9..75fee26f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaConnectorRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaConnectorRepository.java @@ -7,7 +7,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.List; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaNamespaceRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaNamespaceRepository.java index 3d9260e7..c40784fe 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaNamespaceRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaNamespaceRepository.java @@ -7,7 +7,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaRoleBindingRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaRoleBindingRepository.java index 37939748..ec03e3d3 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaRoleBindingRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaRoleBindingRepository.java @@ -7,7 +7,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStore.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStore.java index a4781d9c..587ead65 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStore.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStore.java @@ -19,8 +19,8 @@ import org.apache.kafka.common.errors.TopicExistsException; import javax.annotation.PostConstruct; -import jakarta.inject.Inject; -import jakarta.inject.Named; +import javax.inject.Inject; +import javax.inject.Named; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStreamRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStreamRepository.java index 72018b1e..53ed681a 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStreamRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaStreamRepository.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.stream.Collectors; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import com.michelin.ns4kafka.models.KafkaStream; import com.michelin.ns4kafka.repositories.StreamRepository; diff --git a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaTopicRepository.java b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaTopicRepository.java index 74699346..987dc53e 100644 --- a/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaTopicRepository.java +++ b/api/src/main/java/com/michelin/ns4kafka/repositories/kafka/KafkaTopicRepository.java @@ -10,7 +10,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.List; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRule.java b/api/src/main/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRule.java index a6d35398..009e4d8d 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRule.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRule.java @@ -4,20 +4,18 @@ import com.michelin.ns4kafka.repositories.NamespaceRepository; import com.michelin.ns4kafka.repositories.RoleBindingRepository; import io.micronaut.core.annotation.Nullable; -import io.micronaut.core.async.publisher.Publishers; import io.micronaut.core.util.StringUtils; import io.micronaut.http.HttpRequest; -import io.micronaut.security.authentication.Authentication; import io.micronaut.security.rules.SecurityRule; import io.micronaut.security.rules.SecurityRuleResult; import io.micronaut.web.router.RouteMatch; -import jakarta.inject.Singleton; import lombok.extern.slf4j.Slf4j; -import org.reactivestreams.Publisher; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -41,24 +39,18 @@ public ResourceBasedSecurityRule(SecurityConfig securityConfig, RoleBindingRepos this.roleBindingRepository = roleBindingRepository; this.namespaceRepository = namespaceRepository; } - @Override - public Publisher check(HttpRequest request, @Nullable RouteMatch routeMatch, @Nullable Authentication authentication) { - return Publishers.just(check_security(request, routeMatch, authentication)); - } - public SecurityRuleResult check_security(HttpRequest request, @Nullable RouteMatch routeMatch, @Nullable Authentication authentication) { + @Override + public SecurityRuleResult check(HttpRequest request, @Nullable RouteMatch routeMatch, @Nullable Map claims) { //Unauthenticated request - if(authentication == null){ - return SecurityRuleResult.UNKNOWN; - } - if (!authentication.getAttributes().keySet().containsAll( List.of("groups", "sub", "roles"))) { + if (claims == null || !claims.keySet().containsAll( List.of("groups", "sub", "roles"))) { log.debug("No Authentication available for path [{}]. Returning unknown.",request.getPath()); return SecurityRuleResult.UNKNOWN; } - String sub = authentication.getName(); - List groups = (List) authentication.getAttributes().get("groups"); - Collection roles = authentication.getRoles(); + String sub = claims.get("sub").toString(); + List groups = (List) claims.get("groups"); + List roles = (List) claims.get("roles"); //Request to a URL that is not in the scope of this SecurityRule Matcher matcher = namespacedResourcePattern.matcher(request.getPath()); diff --git a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabApiClient.java b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabApiClient.java index 04f8bbd4..63aea6bb 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabApiClient.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabApiClient.java @@ -4,11 +4,13 @@ import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Header; import io.micronaut.http.client.annotation.Client; -import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.Flowable; import java.util.List; import java.util.Map; +import static io.micronaut.http.HttpRequest.GET; + @Client("${micronaut.security.gitlab.url}") public interface GitlabApiClient { @Get("/api/v4/groups?min_access_level=10&sort=asc&page={page}") diff --git a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationProvider.java b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationProvider.java index a39ac78a..d6f10a03 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationProvider.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationProvider.java @@ -1,17 +1,17 @@ package com.michelin.ns4kafka.security.gitlab; import com.michelin.ns4kafka.security.ResourceBasedSecurityRule; -import io.micronaut.core.annotation.Nullable; +import edu.umd.cs.findbugs.annotations.Nullable; import io.micronaut.http.HttpRequest; import io.micronaut.security.authentication.*; -import io.reactivex.rxjava3.core.BackpressureStrategy; -import io.reactivex.rxjava3.core.Flowable; -import io.reactivex.rxjava3.schedulers.Schedulers; +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; +import io.reactivex.schedulers.Schedulers; import lombok.extern.slf4j.Slf4j; import org.reactivestreams.Publisher; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Map; @@ -35,7 +35,8 @@ public Publisher authenticate(@Nullable HttpRequest h String username = gitlabAuthenticationService.findUsername(token).blockingGet(); List groups = gitlabAuthenticationService.findAllGroups(token).toList().blockingGet(); - AuthenticationResponse user = AuthenticationResponse.success(username, resourceBasedSecurityRule.computeRolesFromGroups(groups), Map.of("groups", groups)); + UserDetails user = new UserDetails(username, resourceBasedSecurityRule.computeRolesFromGroups(groups), Map.of("groups", groups)); + emitter.onNext(user); emitter.onComplete(); }catch (Exception e){ diff --git a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationService.java b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationService.java index 87daa01f..d222e959 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationService.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/gitlab/GitlabAuthenticationService.java @@ -2,16 +2,18 @@ import io.micronaut.core.util.StringUtils; import io.micronaut.http.HttpResponse; -import io.reactivex.rxjava3.core.Flowable; -import io.reactivex.rxjava3.core.Maybe; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import io.reactivex.Flowable; +import io.reactivex.Maybe; import lombok.extern.slf4j.Slf4j; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static io.micronaut.http.HttpRequest.GET; + @Slf4j @Singleton public class GitlabAuthenticationService { diff --git a/api/src/main/java/com/michelin/ns4kafka/security/ldap/LdapAuthenticationMapper.java b/api/src/main/java/com/michelin/ns4kafka/security/ldap/LdapAuthenticationMapper.java index 1bfb4a6e..edfd79ee 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/ldap/LdapAuthenticationMapper.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/ldap/LdapAuthenticationMapper.java @@ -1,17 +1,18 @@ package com.michelin.ns4kafka.security.ldap; import com.michelin.ns4kafka.security.ResourceBasedSecurityRule; +import io.micronaut.configuration.security.ldap.ContextAuthenticationMapper; +import io.micronaut.configuration.security.ldap.DefaultContextAuthenticationMapper; +import io.micronaut.configuration.security.ldap.configuration.LdapConfiguration; import io.micronaut.context.annotation.Replaces; import io.micronaut.context.annotation.Requires; import io.micronaut.core.convert.value.ConvertibleValues; import io.micronaut.core.util.StringUtils; import io.micronaut.security.authentication.AuthenticationResponse; -import io.micronaut.security.ldap.ContextAuthenticationMapper; -import io.micronaut.security.ldap.DefaultContextAuthenticationMapper; -import io.micronaut.security.ldap.configuration.LdapConfiguration; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import io.micronaut.security.authentication.UserDetails; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.Set; @@ -25,6 +26,6 @@ public class LdapAuthenticationMapper implements ContextAuthenticationMapper { ResourceBasedSecurityRule resourceBasedSecurityRule; @Override public AuthenticationResponse map(ConvertibleValues attributes, String username, Set groups) { - return AuthenticationResponse.success(username, resourceBasedSecurityRule.computeRolesFromGroups(List.copyOf(groups)), Map.of("groups",groups)); + return new UserDetails(username, resourceBasedSecurityRule.computeRolesFromGroups(List.copyOf(groups)), Map.of("groups",groups)); } } diff --git a/api/src/main/java/com/michelin/ns4kafka/security/local/LocalUserAuthenticationProvider.java b/api/src/main/java/com/michelin/ns4kafka/security/local/LocalUserAuthenticationProvider.java index ac8d588d..f5a96d6f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/security/local/LocalUserAuthenticationProvider.java +++ b/api/src/main/java/com/michelin/ns4kafka/security/local/LocalUserAuthenticationProvider.java @@ -2,16 +2,16 @@ import com.michelin.ns4kafka.security.ResourceBasedSecurityRule; import com.michelin.ns4kafka.security.SecurityConfig; -import io.micronaut.core.annotation.Nullable; +import edu.umd.cs.findbugs.annotations.Nullable; import io.micronaut.http.HttpRequest; import io.micronaut.security.authentication.*; -import io.reactivex.rxjava3.core.BackpressureStrategy; -import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; import org.reactivestreams.Publisher; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; import java.util.Optional; @@ -35,7 +35,7 @@ public Publisher authenticate(@Nullable HttpRequest h .filter(localUser -> localUser.isValidPassword(password)) .findFirst(); if (authenticatedUser.isPresent()) { - AuthenticationResponse user = AuthenticationResponse.success(username, + UserDetails user = new UserDetails(username, resourceBasedSecurityRule.computeRolesFromGroups(authenticatedUser.get().getGroups()), Map.of("groups", authenticatedUser.get().getGroups())); emitter.onNext(user); diff --git a/api/src/main/java/com/michelin/ns4kafka/services/AccessControlEntryService.java b/api/src/main/java/com/michelin/ns4kafka/services/AccessControlEntryService.java index eb170e52..49bfda46 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/AccessControlEntryService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/AccessControlEntryService.java @@ -5,8 +5,8 @@ import com.michelin.ns4kafka.repositories.AccessControlEntryRepository; import io.micronaut.context.ApplicationContext; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.List; import java.util.Optional; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/ConsumerGroupService.java b/api/src/main/java/com/michelin/ns4kafka/services/ConsumerGroupService.java index 094e7484..62df9fb4 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/ConsumerGroupService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/ConsumerGroupService.java @@ -9,8 +9,8 @@ import io.micronaut.inject.qualifiers.Qualifiers; import org.apache.kafka.common.TopicPartition; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.time.Duration; import java.time.Instant; import java.time.OffsetDateTime; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/KafkaConnectService.java b/api/src/main/java/com/michelin/ns4kafka/services/KafkaConnectService.java index bf0465a0..105f649a 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/KafkaConnectService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/KafkaConnectService.java @@ -16,8 +16,8 @@ import io.micronaut.inject.qualifiers.Qualifiers; import lombok.extern.slf4j.Slf4j; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Locale; import java.util.Optional; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/NamespaceService.java b/api/src/main/java/com/michelin/ns4kafka/services/NamespaceService.java index e2bdc10c..8d87b11f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/NamespaceService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/NamespaceService.java @@ -4,8 +4,8 @@ import com.michelin.ns4kafka.repositories.NamespaceRepository; import com.michelin.ns4kafka.services.executors.KafkaAsyncExecutorConfig; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.List; import java.util.Optional; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/RoleBindingService.java b/api/src/main/java/com/michelin/ns4kafka/services/RoleBindingService.java index 0d09d88f..05fbd51f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/RoleBindingService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/RoleBindingService.java @@ -3,8 +3,8 @@ import com.michelin.ns4kafka.models.RoleBinding; import com.michelin.ns4kafka.repositories.RoleBindingRepository; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Optional; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/StreamService.java b/api/src/main/java/com/michelin/ns4kafka/services/StreamService.java index d6cb001b..232dfab2 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/StreamService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/StreamService.java @@ -3,8 +3,8 @@ import com.michelin.ns4kafka.models.*; import com.michelin.ns4kafka.repositories.StreamRepository; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.*; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/TopicService.java b/api/src/main/java/com/michelin/ns4kafka/services/TopicService.java index c6c0088e..965069eb 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/TopicService.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/TopicService.java @@ -8,8 +8,8 @@ import org.apache.kafka.clients.admin.RecordsToDelete; import org.apache.kafka.common.TopicPartition; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/connect/KafkaConnectClientProxy.java b/api/src/main/java/com/michelin/ns4kafka/services/connect/KafkaConnectClientProxy.java index 8dd15a06..ccfeab6f 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/connect/KafkaConnectClientProxy.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/connect/KafkaConnectClientProxy.java @@ -11,18 +11,18 @@ import io.micronaut.http.MutableHttpResponse; import io.micronaut.http.annotation.Filter; import io.micronaut.http.client.ProxyHttpClient; -import io.micronaut.http.filter.HttpServerFilter; +import io.micronaut.http.filter.OncePerRequestHttpServerFilter; import io.micronaut.http.filter.ServerFilterChain; -import jakarta.inject.Inject; import org.reactivestreams.Publisher; +import javax.inject.Inject; import java.net.URI; import java.util.List; import java.util.Optional; import java.util.UUID; @Filter(KafkaConnectClientProxy.PROXY_PREFIX + "/**") -public class KafkaConnectClientProxy implements HttpServerFilter { +public class KafkaConnectClientProxy extends OncePerRequestHttpServerFilter { public static final String PROXY_PREFIX = "/connect-proxy"; public static final String PROXY_HEADER_KAFKA_CLUSTER = "X-Kafka-Cluster"; public static final String PROXY_HEADER_CONNECT_CLUSTER = "X-Connect-Cluster"; @@ -38,7 +38,7 @@ public class KafkaConnectClientProxy implements HttpServerFilter { List kafkaAsyncExecutorConfigs; @Override - public Publisher> doFilter(HttpRequest request, ServerFilterChain chain) { + public Publisher> doFilterOnce(HttpRequest request, ServerFilterChain chain) { // check call is initiated from micronaut and not from outisde if (!request.getHeaders().contains(KafkaConnectClientProxy.PROXY_HEADER_SECRET)) { return Publishers.just(new ResourceValidationException(List.of("Missing required Header " + KafkaConnectClientProxy.PROXY_HEADER_SECRET), null, null)); diff --git a/api/src/main/java/com/michelin/ns4kafka/services/executors/AccessControlEntryAsyncExecutor.java b/api/src/main/java/com/michelin/ns4kafka/services/executors/AccessControlEntryAsyncExecutor.java index 8ff04971..a1ae12e6 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/executors/AccessControlEntryAsyncExecutor.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/executors/AccessControlEntryAsyncExecutor.java @@ -19,8 +19,8 @@ import org.apache.kafka.common.resource.ResourcePattern; import org.apache.kafka.common.resource.ResourceType; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/executors/ConnectorAsyncExecutor.java b/api/src/main/java/com/michelin/ns4kafka/services/executors/ConnectorAsyncExecutor.java index 89206c56..5e75ff5e 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/executors/ConnectorAsyncExecutor.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/executors/ConnectorAsyncExecutor.java @@ -11,8 +11,8 @@ import io.micronaut.http.client.exceptions.ReadTimeoutException; import lombok.extern.slf4j.Slf4j; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.stream.Collectors; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/executors/ConsumerGroupAsyncExecutor.java b/api/src/main/java/com/michelin/ns4kafka/services/executors/ConsumerGroupAsyncExecutor.java index a422aed1..4fea82dc 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/executors/ConsumerGroupAsyncExecutor.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/executors/ConsumerGroupAsyncExecutor.java @@ -8,7 +8,7 @@ import org.apache.kafka.clients.consumer.OffsetAndMetadata; import org.apache.kafka.common.TopicPartition; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/executors/KafkaAsyncExecutorScheduler.java b/api/src/main/java/com/michelin/ns4kafka/services/executors/KafkaAsyncExecutorScheduler.java index 0adf8c34..7f2ca533 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/executors/KafkaAsyncExecutorScheduler.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/executors/KafkaAsyncExecutorScheduler.java @@ -7,8 +7,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/api/src/main/java/com/michelin/ns4kafka/services/executors/TopicAsyncExecutor.java b/api/src/main/java/com/michelin/ns4kafka/services/executors/TopicAsyncExecutor.java index de7105c2..12bddc15 100644 --- a/api/src/main/java/com/michelin/ns4kafka/services/executors/TopicAsyncExecutor.java +++ b/api/src/main/java/com/michelin/ns4kafka/services/executors/TopicAsyncExecutor.java @@ -10,8 +10,8 @@ import org.apache.kafka.common.TopicPartition; import org.apache.kafka.common.config.ConfigResource; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.net.MalformedURLException; import java.time.Instant; import java.util.*; diff --git a/api/src/test/java/com/michelin/ns4kafka/controllers/AccessControlListControllerTest.java b/api/src/test/java/com/michelin/ns4kafka/controllers/AccessControlListControllerTest.java index 2861f236..78c86182 100644 --- a/api/src/test/java/com/michelin/ns4kafka/controllers/AccessControlListControllerTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/controllers/AccessControlListControllerTest.java @@ -10,6 +10,7 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; import io.micronaut.security.authentication.Authentication; +import io.micronaut.security.authentication.DefaultAuthentication; import io.micronaut.security.utils.SecurityService; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -238,7 +239,7 @@ void applyAsAdmin_Failure() { .build() ) .build(); - Authentication auth = Authentication.build("admin", Map.of("roles",List.of("isAdmin()"))); + Authentication auth = new DefaultAuthentication("admin", Map.of("roles",List.of("isAdmin()"))); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -265,7 +266,7 @@ void applyAsAdmin_Success() { .build() ) .build(); - Authentication auth = Authentication.build("admin", Map.of("roles",List.of("isAdmin()"))); + Authentication auth = new DefaultAuthentication("admin", Map.of("roles",List.of("isAdmin()"))); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -297,7 +298,7 @@ void applyValidationErrors() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -325,7 +326,7 @@ void applySuccess() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -359,7 +360,7 @@ void applySuccess_AlreadyExists() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -403,7 +404,7 @@ void applySuccess_ChangedResource() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -440,7 +441,7 @@ void applyDryRunAdmin() { .build() ) .build(); - Authentication auth = Authentication.build("admin", Map.of("roles",List.of("isAdmin()"))); + Authentication auth = new DefaultAuthentication("admin", Map.of("roles",List.of("isAdmin()"))); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -469,7 +470,7 @@ void applyDryRun() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(namespaceService.findByName("test")) .thenReturn(Optional.of(ns)); @@ -495,7 +496,7 @@ void deleteFailNotFound() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(accessControlEntryService.findByName("test", "ace1")) .thenReturn(Optional.empty()); @@ -517,7 +518,7 @@ void deleteFailSelfAssigned() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(accessControlEntryService.findByName("test", "ace1")) .thenReturn(Optional.of(ace1)); @@ -541,7 +542,7 @@ void deleteSuccessSelfAssigned_AsAdmin() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of("isAdmin()"))); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of("isAdmin()"))); Mockito.when(accessControlEntryService.findByName("test", "ace1")) .thenReturn(Optional.of(ace1)); @@ -564,7 +565,7 @@ void deleteSuccess() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(accessControlEntryService.findByName("test", "ace1")) .thenReturn(Optional.of(ace1)); @@ -590,7 +591,7 @@ void deleteDryRun() { .build() ) .build(); - Authentication auth = Authentication.build("user", Map.of("roles",List.of())); + Authentication auth = new DefaultAuthentication("user", Map.of("roles",List.of())); Mockito.when(accessControlEntryService.findByName("test", "ace1")) .thenReturn(Optional.of(ace1)); diff --git a/api/src/test/java/com/michelin/ns4kafka/controllers/ExceptionHandlerControllerTest.java b/api/src/test/java/com/michelin/ns4kafka/controllers/ExceptionHandlerControllerTest.java index a691b513..5b209392 100644 --- a/api/src/test/java/com/michelin/ns4kafka/controllers/ExceptionHandlerControllerTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/controllers/ExceptionHandlerControllerTest.java @@ -1,6 +1,5 @@ package com.michelin.ns4kafka.controllers; -import io.micronaut.security.authentication.Authentication; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -10,6 +9,7 @@ import io.micronaut.http.HttpStatus; import io.micronaut.security.authentication.AuthenticationException; import io.micronaut.security.authentication.AuthorizationException; +import io.micronaut.security.authentication.DefaultAuthentication; import javax.validation.ConstraintViolationException; import java.util.List; @@ -60,7 +60,7 @@ void authorizationUnauthorizedError() { @Test void authorizationForbiddenError() { var response = exceptionHandlerController.error(HttpRequest.create(HttpMethod.POST, "local") - ,new AuthorizationException(Authentication.build("user", Map.of()))); + ,new AuthorizationException(new DefaultAuthentication("user", Map.of()))); var status = response.body(); Assertions.assertEquals(HttpStatus.FORBIDDEN, response.getStatus()); diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/AccessControlListTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/AccessControlListTest.java index 79579dea..c5eac76e 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/AccessControlListTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/AccessControlListTest.java @@ -1,12 +1,12 @@ package com.michelin.ns4kafka.integration; import com.michelin.ns4kafka.integration.TopicTest.BearerAccessRefreshToken; -import com.michelin.ns4kafka.models.*; import com.michelin.ns4kafka.models.AccessControlEntry; import com.michelin.ns4kafka.models.AccessControlEntry.AccessControlEntrySpec; import com.michelin.ns4kafka.models.AccessControlEntry.Permission; import com.michelin.ns4kafka.models.AccessControlEntry.ResourcePatternType; import com.michelin.ns4kafka.models.AccessControlEntry.ResourceType; +import com.michelin.ns4kafka.models.*; import com.michelin.ns4kafka.models.Namespace.NamespaceSpec; import com.michelin.ns4kafka.models.RoleBinding.*; import com.michelin.ns4kafka.services.executors.AccessControlEntryAsyncExecutor; @@ -15,11 +15,10 @@ import io.micronaut.http.HttpMethod; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; import io.micronaut.security.authentication.UsernamePasswordCredentials; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import jakarta.inject.Inject; import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.common.acl.*; import org.apache.kafka.common.resource.PatternType; @@ -29,6 +28,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import javax.inject.Inject; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; @@ -39,7 +39,7 @@ public class AccessControlListTest extends AbstractIntegrationTest { @Inject @Client("/") - Rx3HttpClient client; + RxHttpClient client; @Inject List accessControlEntryAsyncExecutorList; diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/ConnectTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/ConnectTest.java index 84ac8f06..77cd1581 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/ConnectTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/ConnectTest.java @@ -19,16 +19,15 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; -import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; import io.micronaut.security.authentication.UsernamePasswordCredentials; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import javax.inject.Inject; import java.net.MalformedURLException; import java.net.URL; import java.util.List; @@ -41,9 +40,7 @@ public class ConnectTest extends AbstractIntegrationConnectTest { @Inject @Client("/") - Rx3HttpClient client; - - HttpClient connectClient; + RxHttpClient client; @Inject List topicAsyncExecutorList; @@ -53,8 +50,7 @@ public class ConnectTest extends AbstractIntegrationConnectTest { private String token; @BeforeAll - void init() throws MalformedURLException { - connectClient = HttpClient.create(new URL(connect.getUrl())); + void init() { Namespace ns1 = Namespace.builder() .metadata(ObjectMeta.builder() .name("ns1") @@ -129,8 +125,10 @@ void init() throws MalformedURLException { } @Test - void createConnect() { - ServerInfo actual = connectClient.toBlocking().retrieve(HttpRequest.GET(connect.getUrl()), ServerInfo.class); + void createConnect() throws InterruptedException, ExecutionException, MalformedURLException { + + RxHttpClient connectCli = RxHttpClient.create(new URL(connect.getUrl())); + ServerInfo actual = connectCli.retrieve(HttpRequest.GET("/"), ServerInfo.class).blockingFirst(); Assertions.assertEquals("6.2.0-ccs", actual.version()); } @@ -203,6 +201,7 @@ void restartConnector() throws InterruptedException, ExecutionException, Malform @Test void PauseAndResumeConnector() throws MalformedURLException, InterruptedException { + RxHttpClient connectCli = RxHttpClient.create(new URL(connect.getUrl())); Topic to = Topic.builder() .metadata(ObjectMeta.builder() .name("ns1-to1") @@ -248,7 +247,7 @@ void PauseAndResumeConnector() throws MalformedURLException, InterruptedExceptio Thread.sleep(2000); // verify paused directly on connect cluster - ConnectorStateInfo actual = connectClient.toBlocking().retrieve(HttpRequest.GET("/connectors/ns1-co2/status"), ConnectorStateInfo.class); + ConnectorStateInfo actual = connectCli.retrieve(HttpRequest.GET("/connectors/ns1-co2/status"), ConnectorStateInfo.class).blockingFirst(); Assertions.assertEquals("PAUSED", actual.connector().state()); Assertions.assertEquals("PAUSED", actual.tasks().get(0).state()); Assertions.assertEquals("PAUSED", actual.tasks().get(1).state()); @@ -263,7 +262,7 @@ void PauseAndResumeConnector() throws MalformedURLException, InterruptedExceptio Thread.sleep(2000); // verify resumed directly on connect cluster - actual = connectClient.toBlocking().retrieve(HttpRequest.GET("/connectors/ns1-co2/status"), ConnectorStateInfo.class); + actual = connectCli.retrieve(HttpRequest.GET("/connectors/ns1-co2/status"), ConnectorStateInfo.class).blockingFirst(); Assertions.assertEquals("RUNNING", actual.connector().state()); Assertions.assertEquals("RUNNING", actual.tasks().get(0).state()); Assertions.assertEquals("RUNNING", actual.tasks().get(1).state()); diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/ExceptionHandlerTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/ExceptionHandlerTest.java index 34f62b24..204be361 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/ExceptionHandlerTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/ExceptionHandlerTest.java @@ -1,7 +1,6 @@ package com.michelin.ns4kafka.integration; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; -import jakarta.inject.Inject; +import javax.inject.Inject; import com.michelin.ns4kafka.integration.TopicTest.BearerAccessRefreshToken; import com.michelin.ns4kafka.models.AccessControlEntry; @@ -32,6 +31,7 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; import io.micronaut.security.authentication.UsernamePasswordCredentials; @@ -47,7 +47,7 @@ public class ExceptionHandlerTest extends AbstractIntegrationTest { @Inject @Client("/") - Rx3HttpClient client; + RxHttpClient client; private String token; diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/LoginTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/LoginTest.java index 65a76ef9..06068552 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/LoginTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/LoginTest.java @@ -4,14 +4,14 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; import io.micronaut.security.authentication.UsernamePasswordCredentials; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import jakarta.inject.Inject; +import javax.inject.Inject; @MicronautTest @Property(name = "micronaut.security.gitlab.enabled", value = "false") @@ -19,7 +19,7 @@ public class LoginTest extends AbstractIntegrationTest { @Inject @Client("/") - Rx3HttpClient client; + RxHttpClient client; @Test void login(){ diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/StreamTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/StreamTest.java index 30859e38..adec1696 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/StreamTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/StreamTest.java @@ -14,11 +14,10 @@ import io.micronaut.http.HttpMethod; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; import io.micronaut.security.authentication.UsernamePasswordCredentials; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import jakarta.inject.Inject; import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.common.acl.AccessControlEntryFilter; import org.apache.kafka.common.acl.AclBindingFilter; @@ -29,6 +28,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import javax.inject.Inject; import java.util.List; import java.util.concurrent.ExecutionException; @@ -39,7 +39,7 @@ public class StreamTest extends AbstractIntegrationTest { @Inject @Client("/") - Rx3HttpClient client; + RxHttpClient client; @Inject List aceAsyncExecutorList; diff --git a/api/src/test/java/com/michelin/ns4kafka/integration/TopicTest.java b/api/src/test/java/com/michelin/ns4kafka/integration/TopicTest.java index ce3c4148..a8f51550 100644 --- a/api/src/test/java/com/michelin/ns4kafka/integration/TopicTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/integration/TopicTest.java @@ -18,9 +18,9 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; +import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.rxjava3.http.client.Rx3HttpClient; import io.micronaut.security.authentication.UsernamePasswordCredentials; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import lombok.AllArgsConstructor; @@ -34,7 +34,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.Collection; import java.util.List; import java.util.Map; @@ -49,7 +49,7 @@ public class TopicTest extends AbstractIntegrationTest { @Inject @Client("/") - Rx3HttpClient client; + RxHttpClient client; @Inject List topicAsyncExecutorList; diff --git a/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationProviderTest.java b/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationProviderTest.java index f284cc69..fbebb3da 100644 --- a/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationProviderTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationProviderTest.java @@ -5,9 +5,9 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.client.exceptions.HttpClientResponseException; import io.micronaut.security.authentication.*; -import io.reactivex.rxjava3.core.Flowable; -import io.reactivex.rxjava3.core.Maybe; -import io.reactivex.rxjava3.subscribers.TestSubscriber; +import io.reactivex.Flowable; +import io.reactivex.Maybe; +import io.reactivex.subscribers.TestSubscriber; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -17,7 +17,6 @@ import org.reactivestreams.Publisher; import java.util.List; -import java.util.concurrent.TimeUnit; import static org.mockito.Mockito.when; @@ -46,7 +45,7 @@ public void authenticationSuccess(){ Publisher authenticationResponsePublisher = gitlabAuthenticationProvider.authenticate(null, authenticationRequest); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then @@ -56,11 +55,11 @@ public void authenticationSuccess(){ AuthenticationResponse actual = subscriber.values().get(0); Assertions.assertTrue(actual.isAuthenticated()); - Assertions.assertTrue(actual.getAuthentication().isPresent()); + Assertions.assertTrue(actual.getUserDetails().isPresent()); - Authentication actualUserDetails = actual.getAuthentication().get(); - Assertions.assertEquals("email", actualUserDetails.getName()); - Assertions.assertIterableEquals(groups, (List)actualUserDetails.getAttributes().get( "groups")); + UserDetails actualUserDetails = actual.getUserDetails().get(); + Assertions.assertEquals("email", actualUserDetails.getUsername()); + Assertions.assertIterableEquals(groups, (List)actualUserDetails.getAttributes("roles","username").get( "groups")); Assertions.assertIterableEquals(List.of(), actualUserDetails.getRoles(),"User has no custom roles"); } @@ -81,7 +80,7 @@ public void authenticationSuccessAdmin(){ Publisher authenticationResponsePublisher = gitlabAuthenticationProvider.authenticate(null, authenticationRequest); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then @@ -91,11 +90,11 @@ public void authenticationSuccessAdmin(){ AuthenticationResponse actual = subscriber.values().get(0); Assertions.assertTrue(actual.isAuthenticated()); - Assertions.assertTrue(actual.getAuthentication().isPresent()); + Assertions.assertTrue(actual.getUserDetails().isPresent()); - Authentication actualUserDetails = actual.getAuthentication().get(); - Assertions.assertEquals("email", actualUserDetails.getName()); - Assertions.assertIterableEquals(groups, (List)actualUserDetails.getAttributes().get("groups")); + UserDetails actualUserDetails = actual.getUserDetails().get(); + Assertions.assertEquals("email", actualUserDetails.getUsername()); + Assertions.assertIterableEquals(groups, (List)actualUserDetails.getAttributes("roles","username").get("groups")); Assertions.assertIterableEquals(List.of(ResourceBasedSecurityRule.IS_ADMIN), actualUserDetails.getRoles(),"User has custom roles"); } @@ -112,7 +111,7 @@ public void authenticationFailure(){ Publisher authenticationResponsePublisher = gitlabAuthenticationProvider.authenticate(null, authenticationRequest); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then subscriber.assertError(AuthenticationException.class); diff --git a/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationServiceTest.java b/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationServiceTest.java index e98a41a2..7778bf89 100644 --- a/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationServiceTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/security/GitlabAuthenticationServiceTest.java @@ -3,8 +3,9 @@ import com.michelin.ns4kafka.security.gitlab.GitlabApiClient; import com.michelin.ns4kafka.security.gitlab.GitlabAuthenticationService; import io.micronaut.http.HttpResponse; -import io.reactivex.rxjava3.core.Flowable; -import io.reactivex.rxjava3.subscribers.TestSubscriber; +import io.micronaut.security.authentication.AuthenticationResponse; +import io.reactivex.Flowable; +import io.reactivex.subscribers.TestSubscriber; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -16,7 +17,6 @@ import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; @ExtendWith(MockitoExtension.class) public class GitlabAuthenticationServiceTest { @@ -37,7 +37,7 @@ void findUserSuccess(){ Publisher authenticationResponsePublisher = gitlabAuthenticationService.findUsername(token).toFlowable(); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertComplete(); subscriber.assertNoErrors(); @@ -62,7 +62,7 @@ void findGroupsOnePage(){ Publisher authenticationResponsePublisher = gitlabAuthenticationService.findAllGroups(token); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertComplete(); subscriber.assertNoErrors(); @@ -102,7 +102,7 @@ void findGroupsThreePages(){ Publisher authenticationResponsePublisher = gitlabAuthenticationService.findAllGroups(token); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertComplete(); subscriber.assertNoErrors(); diff --git a/api/src/test/java/com/michelin/ns4kafka/security/LocalUserAuthenticationProviderTest.java b/api/src/test/java/com/michelin/ns4kafka/security/LocalUserAuthenticationProviderTest.java index 862b5f7f..a3c2a0e0 100644 --- a/api/src/test/java/com/michelin/ns4kafka/security/LocalUserAuthenticationProviderTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/security/LocalUserAuthenticationProviderTest.java @@ -2,10 +2,10 @@ import com.michelin.ns4kafka.security.local.LocalUser; import com.michelin.ns4kafka.security.local.LocalUserAuthenticationProvider; -import io.micronaut.security.authentication.Authentication; import io.micronaut.security.authentication.AuthenticationResponse; +import io.micronaut.security.authentication.UserDetails; import io.micronaut.security.authentication.UsernamePasswordCredentials; -import io.reactivex.rxjava3.subscribers.TestSubscriber; +import io.reactivex.subscribers.TestSubscriber; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -17,7 +17,6 @@ import org.reactivestreams.Publisher; import java.util.List; -import java.util.concurrent.TimeUnit; @ExtendWith(MockitoExtension.class) public class LocalUserAuthenticationProviderTest { @@ -39,7 +38,7 @@ void authenticateNoMatchUser() { Publisher authenticationResponsePublisher = localUserAuthenticationProvider.authenticate(null, credentials); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then @@ -61,7 +60,7 @@ void authenticateMatchUserNoMatchPassword() { Publisher authenticationResponsePublisher = localUserAuthenticationProvider.authenticate(null, credentials); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then @@ -86,7 +85,7 @@ void authenticateMatchUserMatchPassword() { Publisher authenticationResponsePublisher = localUserAuthenticationProvider.authenticate(null, credentials); authenticationResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); //then @@ -96,9 +95,9 @@ void authenticateMatchUserMatchPassword() { AuthenticationResponse actual = subscriber.values().get(0); Assertions.assertTrue(actual.isAuthenticated()); - Assertions.assertTrue(actual.getAuthentication().isPresent()); + Assertions.assertTrue(actual.getUserDetails().isPresent()); - Authentication actualUserDetails = actual.getAuthentication().get(); - Assertions.assertEquals("admin", actualUserDetails.getName()); + UserDetails actualUserDetails = actual.getUserDetails().get(); + Assertions.assertEquals("admin", actualUserDetails.getUsername()); } } diff --git a/api/src/test/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRuleTest.java b/api/src/test/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRuleTest.java index 1fd2c2ea..3bd87bd5 100644 --- a/api/src/test/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRuleTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/security/ResourceBasedSecurityRuleTest.java @@ -6,7 +6,6 @@ import com.michelin.ns4kafka.repositories.NamespaceRepository; import com.michelin.ns4kafka.repositories.RoleBindingRepository; import io.micronaut.http.HttpRequest; -import io.micronaut.security.authentication.Authentication; import io.micronaut.security.rules.SecurityRuleResult; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -34,16 +33,14 @@ public class ResourceBasedSecurityRuleTest { @Test void CheckReturnsUnknown_Unauthenticated(){ - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/anything"),null,null); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/anything"),null,null); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @Test void CheckReturnsUnknown_MissingClaims(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups); - Authentication auth = Authentication.build("user", claims); - - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/anything"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/anything"),null,claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @@ -51,9 +48,7 @@ void CheckReturnsUnknown_MissingClaims(){ void CheckReturnsUnknown_InvalidResource(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); - - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/non-namespaced/resource"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/non-namespaced/resource"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @@ -61,13 +56,12 @@ void CheckReturnsUnknown_InvalidResource(){ void CheckReturnsUnknown_NoRoleBinding(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of()); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @@ -75,20 +69,18 @@ void CheckReturnsUnknown_NoRoleBinding(){ void CheckReturnsUnknown_InvalidNamespace(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.empty()); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @Test void CheckReturnsUnknown_AdminNamespaceAsNotAdmin(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/admin/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/admin/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @@ -96,22 +88,20 @@ void CheckReturnsUnknown_AdminNamespaceAsNotAdmin(){ void CheckReturnsUnknown_InvalidNamespaceAsAdmin(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of("isAdmin()")); - Authentication auth = Authentication.build("user", List.of("isAdmin()"), claims); Mockito.when(namespaceRepository.findByName("admin")) .thenReturn(Optional.empty()); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/admin/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/admin/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @Test void CheckReturnsAllowed_NamespaceAsAdmin(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of("isAdmin()")); - Authentication auth = Authentication.build("user", List.of("isAdmin()"), claims); Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); } @@ -119,7 +109,6 @@ void CheckReturnsAllowed_NamespaceAsAdmin(){ void CheckReturnsAllowed(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of(RoleBinding.builder() .metadata(ObjectMeta.builder().namespace("test") @@ -136,14 +125,13 @@ void CheckReturnsAllowed(){ Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); } @Test void CheckReturnsAllowed_Subresource(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of(RoleBinding.builder() .metadata(ObjectMeta.builder().namespace("test") @@ -160,17 +148,16 @@ void CheckReturnsAllowed_Subresource(){ Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects/name/restart"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects/name/restart"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); - actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/topics/name/delete-records"),null, auth); + actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/topics/name/delete-records"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); } @Test void CheckReturnsAllowed_ResourceWithHyphen(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of(RoleBinding.builder() .metadata(ObjectMeta.builder().namespace("test") @@ -187,14 +174,13 @@ void CheckReturnsAllowed_ResourceWithHyphen(){ Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/role-bindings"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/role-bindings"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); } @Test void CheckReturnsAllowed_ResourceNameWithDot(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of(RoleBinding.builder() .metadata(ObjectMeta.builder().namespace("test") @@ -211,7 +197,7 @@ void CheckReturnsAllowed_ResourceNameWithDot(){ Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/topics/topic.with.dots"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/topics/topic.with.dots"),null, claims); Assertions.assertEquals(SecurityRuleResult.ALLOWED, actual); } @@ -219,10 +205,9 @@ void CheckReturnsAllowed_ResourceNameWithDot(){ void CheckReturnsUnknown_SubResource(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); - Mockito.when(roleBindingRepository.findAllForGroups(groups)) + Mockito.when(roleBindingRepository.findAllForGroups(groups)) .thenReturn(List.of(RoleBinding.builder() .metadata(ObjectMeta.builder().namespace("test") .build()) @@ -236,14 +221,13 @@ void CheckReturnsUnknown_SubResource(){ .build()) .build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects/name/restart"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects/name/restart"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } @Test void CheckReturnsUnknown_SubResourceWithDot(){ List groups = List.of("group1"); Map claims = Map.of("sub","user", "groups", groups, "roles", List.of()); - Authentication auth = Authentication.build("user", claims); Mockito.when(namespaceRepository.findByName("test")) .thenReturn(Optional.of(Namespace.builder().build())); Mockito.when(roleBindingRepository.findAllForGroups(groups)) @@ -260,7 +244,7 @@ void CheckReturnsUnknown_SubResourceWithDot(){ .build()) .build())); - SecurityRuleResult actual = resourceBasedSecurityRule.check_security(HttpRequest.GET("/api/namespaces/test/connects/name.with.dots/restart"),null, auth); + SecurityRuleResult actual = resourceBasedSecurityRule.check(HttpRequest.GET("/api/namespaces/test/connects/name.with.dots/restart"),null, claims); Assertions.assertEquals(SecurityRuleResult.UNKNOWN, actual); } diff --git a/api/src/test/java/com/michelin/ns4kafka/services/KafkaConnectClientProxyTest.java b/api/src/test/java/com/michelin/ns4kafka/services/KafkaConnectClientProxyTest.java index 43d211e0..356d62de 100644 --- a/api/src/test/java/com/michelin/ns4kafka/services/KafkaConnectClientProxyTest.java +++ b/api/src/test/java/com/michelin/ns4kafka/services/KafkaConnectClientProxyTest.java @@ -8,7 +8,7 @@ import io.micronaut.http.*; import io.micronaut.http.client.ProxyHttpClient; import io.micronaut.http.simple.SimpleHttpRequest; -import io.reactivex.rxjava3.subscribers.TestSubscriber; +import io.reactivex.subscribers.TestSubscriber; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @ExtendWith(MockitoExtension.class) @@ -41,10 +40,10 @@ void doFilterMissingHeader_Secret() { .header("X-Unused", "123"); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(ResourceValidationException.class); subscriber.assertError(throwable -> @@ -60,10 +59,10 @@ void doFilterWrongSecret() { .header("X-Proxy-Secret", "123"); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(ResourceValidationException.class); subscriber.assertError(throwable -> @@ -80,10 +79,10 @@ void doFilterMissingHeader_KafkaCluster() { .header("X-Unused", "123"); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(ResourceValidationException.class); subscriber.assertError(throwable -> @@ -100,10 +99,10 @@ void doFilterMissingHeader_ConnectCluster() { .header(KafkaConnectClientProxy.PROXY_HEADER_KAFKA_CLUSTER, "local"); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(ResourceValidationException.class); subscriber.assertError(throwable -> @@ -123,10 +122,10 @@ void doFilterWrongKafkaCluster() { Mockito.when(kafkaAsyncExecutorConfigs.stream()).thenReturn(Stream.empty()); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(throwable -> ((ResourceValidationException)throwable) @@ -149,10 +148,10 @@ void doFilterWrongConnectCluster() { .thenReturn(Stream.of(config)); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertError(throwable -> ((ResourceValidationException)throwable) @@ -182,10 +181,10 @@ void doFilterSuccess() { .thenReturn(Publishers.just(HttpResponse.ok())); TestSubscriber> subscriber = new TestSubscriber(); - Publisher> mutableHttpResponsePublisher = proxy.doFilter(request, null); + Publisher> mutableHttpResponsePublisher = proxy.doFilterOnce(request, null); mutableHttpResponsePublisher.subscribe(subscriber); - subscriber.awaitDone(1L, TimeUnit.SECONDS); + subscriber.awaitTerminalEvent(); subscriber.assertValueCount(1); subscriber.assertValue(mutableHttpResponse -> mutableHttpResponse.status() == HttpStatus.OK); diff --git a/build.gradle b/build.gradle index 6491d69b..b28a5e63 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id("com.github.johnrengelman.shadow") version "7.0.0" - id("io.micronaut.application") version "2.0.3" + id("io.micronaut.application") version "1.5.0" id 'jacoco' id "org.sonarqube" version "3.1.1" } diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/ApiResourcesSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/ApiResourcesSubcommand.java index d8e6e110..dd76b109 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/ApiResourcesSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/ApiResourcesSubcommand.java @@ -3,7 +3,7 @@ import com.michelin.ns4kafka.cli.services.ApiResourcesService; import picocli.CommandLine; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.concurrent.Callable; @CommandLine.Command(name = "api-resources", description = "Print the supported API resources on the server") diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/ApplySubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/ApplySubcommand.java index 01274145..4a070b9a 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/ApplySubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/ApplySubcommand.java @@ -11,7 +11,7 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.io.File; import java.util.List; import java.util.Optional; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/ConnectorsSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/ConnectorsSubcommand.java index 10e862e5..fde7f19c 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/ConnectorsSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/ConnectorsSubcommand.java @@ -9,7 +9,7 @@ import com.michelin.ns4kafka.cli.services.ResourceService; import picocli.CommandLine; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Objects; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteRecordsSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteRecordsSubcommand.java index d1b44408..b983ab06 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteRecordsSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteRecordsSubcommand.java @@ -9,7 +9,7 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.concurrent.Callable; @Command(name = "delete-records", description = "Deletes all records within a topic") diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteSubcommand.java index edf7b3ae..77941c6a 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/DeleteSubcommand.java @@ -13,7 +13,7 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.io.File; import java.util.List; import java.util.Optional; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/DiffSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/DiffSubcommand.java index 9c555d1b..7f966e9b 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/DiffSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/DiffSubcommand.java @@ -18,7 +18,7 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.io.File; import java.util.List; import java.util.Optional; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/GetSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/GetSubcommand.java index e1ab63dc..70939c46 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/GetSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/GetSubcommand.java @@ -14,7 +14,7 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Optional; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/ImportSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/ImportSubcommand.java index 1ba3cba3..7965510e 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/ImportSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/ImportSubcommand.java @@ -11,7 +11,7 @@ import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Optional; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/KafkactlCommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/KafkactlCommand.java index 4d5b13ed..db17f36f 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/KafkactlCommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/KafkactlCommand.java @@ -5,8 +5,8 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Optional; import java.util.concurrent.Callable; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/ResetOffsetsSubcommand.java b/cli/src/main/java/com/michelin/ns4kafka/cli/ResetOffsetsSubcommand.java index 24cd01dd..c79ad3d5 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/ResetOffsetsSubcommand.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/ResetOffsetsSubcommand.java @@ -10,7 +10,7 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import jakarta.inject.Inject; +import javax.inject.Inject; import java.time.Duration; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/services/ApiResourcesService.java b/cli/src/main/java/com/michelin/ns4kafka/cli/services/ApiResourcesService.java index 8937f6f0..e8c3993a 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/services/ApiResourcesService.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/services/ApiResourcesService.java @@ -4,8 +4,8 @@ import com.michelin.ns4kafka.cli.models.ApiResource; import com.michelin.ns4kafka.cli.models.Resource; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/services/FileService.java b/cli/src/main/java/com/michelin/ns4kafka/cli/services/FileService.java index 6c0644cc..dc3f2eec 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/services/FileService.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/services/FileService.java @@ -4,7 +4,7 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.nio.file.Files; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/services/FormatService.java b/cli/src/main/java/com/michelin/ns4kafka/cli/services/FormatService.java index 88a67a7a..fec98ecd 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/services/FormatService.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/services/FormatService.java @@ -15,8 +15,8 @@ import org.yaml.snakeyaml.representer.Representer; import picocli.CommandLine; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/services/LoginService.java b/cli/src/main/java/com/michelin/ns4kafka/cli/services/LoginService.java index 4104692c..2d4c5ce0 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/services/LoginService.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/services/LoginService.java @@ -10,7 +10,7 @@ import io.micronaut.http.HttpStatus; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import jakarta.inject.Singleton; +import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.util.Calendar; diff --git a/cli/src/main/java/com/michelin/ns4kafka/cli/services/ResourceService.java b/cli/src/main/java/com/michelin/ns4kafka/cli/services/ResourceService.java index 1bf5c2d9..8a6fe3a2 100644 --- a/cli/src/main/java/com/michelin/ns4kafka/cli/services/ResourceService.java +++ b/cli/src/main/java/com/michelin/ns4kafka/cli/services/ResourceService.java @@ -9,8 +9,8 @@ import io.micronaut.http.HttpStatus; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Map; import java.util.stream.Collectors; diff --git a/gradle.properties b/gradle.properties index d36d8dcf..9208dc28 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -micronautVersion=3.1.4 +micronautVersion=2.5.9 \ No newline at end of file