-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from xenit-eu/feature/spring-boot-starter
Spring boot starters for API and Gateway services
- Loading branch information
Showing
10 changed files
with
325 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
plugins { | ||
id 'java-library' | ||
} | ||
|
||
apply from: "${rootDir}/gradle/publish.gradle" | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
api project(':thunx-spring') | ||
api project(':thunx-autoconfigure') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
plugins { | ||
id 'java-library' | ||
} | ||
|
||
apply from: "${rootDir}/gradle/publish.gradle" | ||
|
||
dependencies { | ||
|
||
compileOnly platform("org.springframework.boot:spring-boot-dependencies:${springBootBomVersion}") | ||
compileOnly platform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}") | ||
|
||
implementation "org.springframework.boot:spring-boot-autoconfigure" | ||
|
||
compileOnly "org.projectlombok:lombok" | ||
|
||
compileOnly project(':thunx-spring') | ||
compileOnly project(':thunx-pdp-opa') | ||
compileOnly "eu.xenit.contentcloud:opa-async-java-client:0.2.0" | ||
|
||
compileOnly 'org.springframework.security:spring-security-web' | ||
|
||
compileOnly 'org.springframework.data:spring-data-rest-core' | ||
compileOnly 'org.springframework.cloud:spring-cloud-starter-gateway' | ||
|
||
annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor:${springBootBomVersion}" | ||
annotationProcessor "org.projectlombok:lombok:${lombokVersion}" | ||
|
||
testImplementation platform("org.springframework.boot:spring-boot-dependencies:${springBootBomVersion}") | ||
testImplementation platform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}") | ||
|
||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testImplementation 'org.assertj:assertj-core:3.21.0' | ||
testImplementation 'org.mockito:mockito-core:2.1.0' | ||
testImplementation "org.springframework.boot:spring-boot-test" | ||
testImplementation "org.springframework.boot:spring-boot-starter-data-jpa" | ||
testImplementation "org.springframework.boot:spring-boot-starter-data-rest" | ||
testImplementation 'org.springframework.security:spring-security-web' | ||
testImplementation 'org.springframework.cloud:spring-cloud-starter-gateway' | ||
testImplementation 'com.h2database:h2:1.4.200' | ||
testImplementation project(':thunx-spring') | ||
testImplementation project(':thunx-pdp-opa') | ||
testImplementation "eu.xenit.contentcloud:opa-async-java-client:0.2.0" | ||
} | ||
|
||
test { | ||
useJUnitPlatform() | ||
} |
16 changes: 16 additions & 0 deletions
16
...re/src/main/java/eu/xenit/contentcloud/thunx/api/autoconfigure/AbacAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package eu.xenit.contentcloud.thunx.api.autoconfigure; | ||
|
||
import eu.xenit.contentcloud.thunx.spring.data.EnableAbac; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||
|
||
@Configuration | ||
@ConditionalOnClass(RepositoryRestResource.class) | ||
public class AbacAutoConfiguration { | ||
|
||
@Configuration | ||
@EnableAbac | ||
public static class EnableAbacAutoConfiguration { | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...main/java/eu/xenit/contentcloud/thunx/gateway/autoconfigure/GatewayAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package eu.xenit.contentcloud.thunx.gateway.autoconfigure; | ||
|
||
import eu.xenit.contentcloud.opa.client.OpaClient; | ||
import eu.xenit.contentcloud.opa.client.rest.RestClientConfiguration; | ||
import eu.xenit.contentcloud.thunx.pdp.PolicyDecisionComponentImpl; | ||
import eu.xenit.contentcloud.thunx.pdp.PolicyDecisionPointClient; | ||
import eu.xenit.contentcloud.thunx.pdp.opa.OpaQueryProvider; | ||
import eu.xenit.contentcloud.thunx.pdp.opa.OpenPolicyAgentPDPClient; | ||
import eu.xenit.contentcloud.thunx.spring.gateway.filter.AbacGatewayFilterFactory; | ||
import eu.xenit.contentcloud.thunx.spring.security.ReactivePolicyAuthorizationManager; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.authorization.ReactiveAuthorizationManager; | ||
import org.springframework.security.web.server.authorization.AuthorizationContext; | ||
|
||
@Configuration | ||
@ConditionalOnClass({OpaClient.class, AbstractGatewayFilterFactory.class}) | ||
@EnableConfigurationProperties(OpaProperties.class) | ||
public class GatewayAutoConfiguration { | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public OpaClient opaClient(OpaProperties opaProperties) { | ||
return OpaClient.builder() | ||
.httpLogging(RestClientConfiguration.LogSpecification::all) | ||
.url(opaProperties.getService().getUrl()) | ||
.build(); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public OpaQueryProvider propertyBasedOpaQueryProvider(OpaProperties opaProperties) { | ||
return request -> opaProperties.getQuery(); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public PolicyDecisionPointClient pdpClient(OpaClient opaClient, OpaQueryProvider queryProvider) { | ||
return new OpenPolicyAgentPDPClient(opaClient, queryProvider); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public ReactiveAuthorizationManager<AuthorizationContext> reactiveAuthenticationManager( | ||
PolicyDecisionPointClient pdpClient) { | ||
return new ReactivePolicyAuthorizationManager(new PolicyDecisionComponentImpl(pdpClient)); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public AbacGatewayFilterFactory abacGatewayFilterFactory() { | ||
return new AbacGatewayFilterFactory(); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...figure/src/main/java/eu/xenit/contentcloud/thunx/gateway/autoconfigure/OpaProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package eu.xenit.contentcloud.thunx.gateway.autoconfigure; | ||
|
||
import lombok.Data; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
@Data | ||
@ConfigurationProperties(prefix = "opa") | ||
public class OpaProperties { | ||
private OpaServiceProperties service; | ||
private String query; | ||
|
||
@Data | ||
public static class OpaServiceProperties { | ||
private String url; | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
thunx-autoconfigure/src/main/resources/META-INF/spring.factories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Auto Configure | ||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ | ||
eu.xenit.contentcloud.thunx.api.autoconfigure.AbacAutoConfiguration,\ | ||
eu.xenit.contentcloud.thunx.gateway.autoconfigure.GatewayAutoConfiguration |
50 changes: 50 additions & 0 deletions
50
...rc/test/java/eu/xenit/contentcloud/thunx/api/autoconfigure/AbacAutoConfigurationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package eu.xenit.contentcloud.thunx.api.autoconfigure; | ||
|
||
import eu.xenit.contentcloud.thunx.encoding.ThunkExpressionDecoder; | ||
import eu.xenit.contentcloud.thunx.spring.data.rest.AbacExceptionHandler; | ||
import eu.xenit.contentcloud.thunx.spring.data.rest.AbacRequestFilter; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.autoconfigure.AutoConfigurations; | ||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; | ||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.repository.support.Repositories; | ||
|
||
import static org.hamcrest.CoreMatchers.*; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
|
||
public class AbacAutoConfigurationTest { | ||
|
||
@Test | ||
public void shouldEnableAbac() { | ||
|
||
ApplicationContextRunner contextRunner = new ApplicationContextRunner() | ||
.withConfiguration(AutoConfigurations.of( | ||
AbacAutoConfiguration.class | ||
)); | ||
|
||
contextRunner.withUserConfiguration(TestContext.class).run((context) -> { | ||
assertThat(context.getBean(ThunkExpressionDecoder.class), is(not(nullValue()))); | ||
assertThat(context.getBean(AbacExceptionHandler.class), is(not(nullValue()))); | ||
assertThat(context.getBean(AbacRequestFilter.class), is(not(nullValue()))); | ||
assertThat(context.getBean("abacFilterRegistration"), is(not(nullValue()))); | ||
assertThat(context.getBean("interceptRepositoryRestMvcConfiguration"), is(not(nullValue()))); | ||
assertThat(context.getBean("ensureQueryDslPredication"), is(not(nullValue()))); | ||
}); | ||
} | ||
|
||
@Configuration | ||
@EnableAutoConfiguration(exclude={ | ||
org.springframework.cloud.gateway.config.GatewayAutoConfiguration.class, | ||
eu.xenit.contentcloud.thunx.gateway.autoconfigure.GatewayAutoConfiguration.class | ||
}) | ||
public static class TestContext { | ||
|
||
@Bean | ||
public Repositories repositories(ApplicationContext context) { | ||
return new Repositories(context); | ||
} | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
.../java/eu/xenit/contentcloud/thunx/gateway/autoconfigure/GatewayAutoConfigurationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package eu.xenit.contentcloud.thunx.gateway.autoconfigure; | ||
|
||
import eu.xenit.contentcloud.opa.client.OpaClient; | ||
import eu.xenit.contentcloud.thunx.pdp.PolicyDecisionPointClient; | ||
import eu.xenit.contentcloud.thunx.pdp.opa.OpaQueryProvider; | ||
import eu.xenit.contentcloud.thunx.spring.gateway.filter.AbacGatewayFilterFactory; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.autoconfigure.AutoConfigurations; | ||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.security.authorization.ReactiveAuthorizationManager; | ||
import org.springframework.security.web.server.authorization.AuthorizationContext; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.mock; | ||
|
||
public class GatewayAutoConfigurationTest { | ||
|
||
@Test | ||
public void shouldEnableGatewayBeans() { | ||
|
||
ApplicationContextRunner contextRunner = new ApplicationContextRunner() | ||
.withConfiguration(AutoConfigurations.of( | ||
GatewayAutoConfiguration.class | ||
)); | ||
|
||
contextRunner.withUserConfiguration(TestContext.class) | ||
.withPropertyValues("opa.service.url=https://some/opa/service") | ||
.run((context) -> { | ||
assertThat(context.getBean(OpaClient.class)).isNotNull(); | ||
assertThat(context.getBean(OpaQueryProvider.class)).isNotNull(); | ||
assertThat(context.getBean(PolicyDecisionPointClient.class)).isNotNull(); | ||
assertThat(context.getBean(ReactiveAuthorizationManager.class)).isNotNull(); | ||
assertThat(context.getBean(AbacGatewayFilterFactory.class)).isNotNull(); | ||
}); | ||
} | ||
|
||
@Test | ||
public void shouldUseProvidedGatewayBeans() { | ||
|
||
ApplicationContextRunner contextRunner = new ApplicationContextRunner() | ||
.withConfiguration(AutoConfigurations.of( | ||
GatewayAutoConfiguration.class | ||
)); | ||
|
||
contextRunner.withUserConfiguration(TestContextWithBeans.class) | ||
.run((context) -> { | ||
assertThat(context.getBean(OpaClient.class)).isSameAs(context.getBean(TestContextWithBeans.class).opaClient()); | ||
assertThat(context.getBean(OpaQueryProvider.class)).isSameAs(context.getBean(TestContextWithBeans.class).customQueryProvider()); | ||
assertThat(context.getBean(PolicyDecisionPointClient.class)).isSameAs(context.getBean(TestContextWithBeans.class).pdpClient()); | ||
assertThat(context.getBean(ReactiveAuthorizationManager.class)).isSameAs(context.getBean(TestContextWithBeans.class).reactiveAuthenticationManager()); | ||
assertThat(context.getBean(AbacGatewayFilterFactory.class)).isSameAs(context.getBean(TestContextWithBeans.class).abacGatewayFilterFactory()); | ||
}); | ||
} | ||
|
||
@Configuration | ||
@EnableAutoConfiguration(exclude={ | ||
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.class, | ||
org.springframework.cloud.gateway.config.GatewayAutoConfiguration.class, | ||
eu.xenit.contentcloud.thunx.api.autoconfigure.AbacAutoConfiguration.class | ||
}) | ||
public static class TestContext { | ||
} | ||
|
||
@Configuration | ||
@EnableAutoConfiguration(exclude={ | ||
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.class, | ||
org.springframework.cloud.gateway.config.GatewayAutoConfiguration.class, | ||
eu.xenit.contentcloud.thunx.api.autoconfigure.AbacAutoConfiguration.class | ||
}) | ||
public static class TestContextWithBeans { | ||
|
||
@Bean | ||
public OpaClient opaClient() { | ||
return mock(OpaClient.class); | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public PolicyDecisionPointClient pdpClient() { | ||
return mock(PolicyDecisionPointClient.class); | ||
} | ||
|
||
@Bean | ||
public ReactiveAuthorizationManager<AuthorizationContext> reactiveAuthenticationManager() { | ||
return mock(ReactiveAuthorizationManager.class); | ||
} | ||
|
||
@Bean | ||
public AbacGatewayFilterFactory abacGatewayFilterFactory() { | ||
return mock(AbacGatewayFilterFactory.class); | ||
} | ||
|
||
@Bean | ||
public OpaQueryProvider customQueryProvider() { | ||
return mock(OpaQueryProvider.class); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
plugins { | ||
id 'java-library' | ||
} | ||
|
||
apply from: "${rootDir}/gradle/publish.gradle" | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
api project(':thunx-pdp-opa') | ||
api project(':thunx-autoconfigure') | ||
} |