Skip to content

Commit

Permalink
Spring Boot 2 support #297
Browse files Browse the repository at this point in the history
  • Loading branch information
remmeier committed Apr 25, 2018
1 parent a04671a commit 8b95571
Show file tree
Hide file tree
Showing 147 changed files with 3,499 additions and 84 deletions.
14 changes: 4 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ gradle.beforeProject { Project project ->
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE'
mavenBom 'io.projectreactor:reactor-bom:Bismuth-RELEASE'
mavenBom 'org.glassfish.jersey:jersey-bom:2.26'
}
Expand All @@ -98,8 +97,6 @@ gradle.beforeProject { Project project ->
}

if (!docs && !examples && !testProject && !legacyBraveProject) {
// https://about.sonarqube.com/get-started/
apply plugin: "org.sonarqube"
apply plugin: "jacoco"

jacoco {
Expand All @@ -114,6 +111,8 @@ gradle.beforeProject { Project project ->

def mainOutput = files(files(sourceSets.main.output).collect {
fileTree(dir: it, exclude: '**/legacy/**')
fileTree(dir: it, exclude: '**/crnk-setup-spring-boot1/**')
fileTree(dir: it, exclude: '**/crnk-brave/**')
})

if (sourceDirs == null) {
Expand All @@ -127,13 +126,6 @@ gradle.beforeProject { Project project ->
}
rootProject.coveralls.sourceDirs.addAll(sourceSets.main.allSource.srcDirs.flatten())


sonarqube {
properties {
property 'sonar.coverage.exclusions', "**/legacy/**"
}
}

jacocoTestReport {
reports {
xml.enabled = true // coveralls plugin depends on xml format report
Expand Down Expand Up @@ -167,6 +159,8 @@ gradle.beforeProject { Project project ->
archives sourcesJar
}

ext.'signing.secretKeyRingFile' = "${rootProject.projectDir}/secring.gpg"

signing {
required {
gradle.taskGraph.hasTask("uploadArchives")
Expand Down
2 changes: 1 addition & 1 deletion crnk-documentation/src/docs/asciidoc/modules.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ is registered as `JpaRelationshipRepository`.
environment (Spring, JEE, etc.). This might be as simple as a Spring bean implementing `TransactionRunner` and adding a
`@Transactional` annotation. The JPA module makes sure that every call to a repository happens within such a transaction
boundary. Crnk comes with two default implementations: `SpringTransactionRunner` and
`CdiTransactionRunner` that come are included in `crnk-spring` and `crnk-cdi`.
`CdiTransactionRunner` that come are included in `crnk-setup-spring` and `crnk-cdi`.
For crnk-client it might be worthwhile to have an interface definition of the otherwise fully generic
JSON API entity repositories. The interface has the benefit of providing proper typing of meta information,
Expand Down
38 changes: 23 additions & 15 deletions crnk-documentation/src/docs/asciidoc/setup.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The crnk modules can then simply be used without having to specify a version:
----
dependencies {
compile 'io.crnk:crnk-rs'
compile 'io.crnk:crnk-spring'
compile 'io.crnk:crnk-setup-spring-boot2'
...
}
----
Expand Down Expand Up @@ -246,30 +246,38 @@ A code below shows a sample ``web.xml`` file with properly defined and configure

## Integration with Spring and String Boot

Crnk provides with `crnk-spring` a number of utilities to seamlessly integrate with Spring and Spring Boot.
First and foremost, there is a ``CrnkConfigV3`` configuration class to hook Crnk into Spring Web to serve requests.
Crnk provides with:

Spring integration uses crnk-servlet ``CrnkFilter`` to fetch the requests. Similar to CDI, repositories
and modules are picked up from the Spring ApplicationContext with ``SpringServiceDiscovery``.
- `io-crnk:crnk-setup-spring` support for plain Spring 4 and 5.
- `io-crnk:crnk-setup-spring-boot1` support for Spring Boot 1.x. This module is considered being deprecated and will be removed in the future.
- `io-crnk:crnk-setup-spring-boot2` support for Spring Boot 2.x.
Next to the Spring Web integration, `crnk-spring` provides a number modules to hook into other Spring components.
For a detailed overview see <<spring_modules,Spring modules>>.
The web integration can be customized with the subsequent properties:
There is a `CrnkCoreAutoConfiguration` in `crnk-setup-spring-boot2` that outlines
the basic setup that can easily be applied to a Spring-only setup without Spring Boot using `crnk-setup-spring`:

- It uses the `CrnkFilter` servlet filter to fetch the requests.
- Service discovery is performed with `SpringServiceDiscovery` using the Spring `ApplicationContext`.
There are further auto configurations that automatically setup various Crnk modules. And there are also further integrations into Spring (like for `RestTemplate`
and Spring Security). More information is available in <<spring_modules,Spring modules>>.

The web integration can be customized for Spring Boot setups with the subsequent properties:

[source]
.application.properties
----
crnk.enabled=true
crnk.domainName=http://localhost:8080
crnk.pathPrefix=/api
crnk.defaultPageLimit=20
crnk.maxPageLimit=1000
crnk.allowUnknownAttributes=false
crnk.return404OnNull=true
crnk.domain-name=http://localhost:8080
crnk.path-prefix=/api
crnk.default-page-limit=20
crnk.max-page-limit=1000
crnk.allow-unknown-attributes=false
crnk.return404-on-null=true
----

See https://github.com/crnk-project/crnk-framework/blob/master/crnk-spring/src/main/java/io/crnk/spring/boot/CrnkSpringBootProperties.java[CrnkBootProperties] for more information.
See https://github.com/crnk-project/crnk-framework/blob/master/crnk-setup/crnk-setup-spring-boot2/src/main/java/io/crnk/setup/spring/boot/core/CrnkCoreProperties.java[CrnkCoreProperties] for more information.
The <<spring_modules,Spring modules>> and their auto configurations make further configuration properties available.


Expand Down
2 changes: 1 addition & 1 deletion crnk-examples/spring-boot-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mainClassName = "io.crnk.example.springboot.SpringBootExampleApplication"
dependencies {

compile project(':crnk-rs')
compile project(':crnk-spring')
compile project(':crnk-legacy:crnk-spring')
compile project(':crnk-jpa')
compile project(':crnk-validation')
compile project(':crnk-home')
Expand Down
6 changes: 6 additions & 0 deletions crnk-legacy/crnk-spring/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apply plugin: 'java'

dependencies {
compile project(':crnk-setup:crnk-setup-spring')
compile project(':crnk-setup:crnk-setup-spring-boot1')
}
2 changes: 1 addition & 1 deletion crnk-operations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies {
testCompile project(':crnk-rs')
testCompile project(':crnk-test')
testCompile project(':crnk-jpa')
testCompile project(':crnk-spring')
testCompile project(':crnk-setup:crnk-setup-spring')
testCompile project(':crnk-validation')

compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
Expand Down
3 changes: 1 addition & 2 deletions crnk-reactive/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ dependencies {
testCompile 'io.projectreactor:reactor-test'
testCompile 'ch.qos.logback:logback-classic:1.2.3'

compile 'org.springframework.boot:spring-boot-starter-test'

compile 'org.springframework.boot:spring-boot-starter-test:1.5.8.RELEASE'
}
4 changes: 2 additions & 2 deletions crnk-servlet/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies {
testCompile group: 'org.reflections', name: 'reflections', version: '0.9.9'
testCompile 'javax.servlet:javax.servlet-api:3.1.0'

testCompile 'org.springframework.boot:spring-boot-starter-web'
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE'
testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.8.RELEASE'
testCompile 'net.javacrumbs.json-unit:json-unit:1.5.5'
}
47 changes: 24 additions & 23 deletions crnk-servlet/src/main/java/io/crnk/servlet/CrnkFilter.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.crnk.servlet;

import io.crnk.core.boot.CrnkBoot;
import io.crnk.core.engine.dispatcher.RequestDispatcher;
import io.crnk.core.engine.http.HttpHeaders;
import io.crnk.core.engine.http.HttpRequestContextProvider;
import io.crnk.core.engine.internal.utils.UrlUtils;
import io.crnk.servlet.internal.FilterPropertiesProvider;
import io.crnk.servlet.internal.ServletModule;
import io.crnk.servlet.internal.ServletRequestContext;
Expand All @@ -44,17 +29,27 @@ public class CrnkFilter implements Filter {

private String defaultCharacterEncoding = HttpHeaders.DEFAULT_CHARSET;

public CrnkFilter() {

}

public CrnkFilter(CrnkBoot boot) {
this.boot = boot;
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;

boot = new CrnkBoot();
boot.setPropertiesProvider(new FilterPropertiesProvider(filterConfig));
if (boot == null) {
boot = new CrnkBoot();
boot.setPropertiesProvider(new FilterPropertiesProvider(filterConfig));

HttpRequestContextProvider provider = boot.getModuleRegistry().getHttpRequestContextProvider();
boot.addModule(new ServletModule(provider));
initCrnk(boot);
boot.boot();
HttpRequestContextProvider provider = boot.getModuleRegistry().getHttpRequestContextProvider();
boot.addModule(new ServletModule(provider));
initCrnk(boot);
boot.boot();
}
}

public String getDefaultCharacterEncoding() {
Expand All @@ -76,7 +71,7 @@ public void destroy() {

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse && matchesPrefix((HttpServletRequest) req)) {
ServletContext servletContext = filterConfig.getServletContext();
ServletRequestContext context = new ServletRequestContext(servletContext, (HttpServletRequest) req,
(HttpServletResponse) res, boot.getWebPathPrefix(), defaultCharacterEncoding);
Expand All @@ -90,4 +85,10 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
}
}

private boolean matchesPrefix(HttpServletRequest request) {
String pathPrefix = UrlUtils.removeLeadingSlash(boot.getWebPathPrefix());
String path = UrlUtils.removeLeadingSlash(request.getRequestURI().substring(request.getContextPath().length()));
return pathPrefix == null || path.startsWith(pathPrefix);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,14 @@ public String getPath() {

@Override
public String getBaseUrl() {
String requestUrl = servletRequest.getRequestURL().toString();
String servletPath = servletRequest.getServletPath();
String requestUrl = UrlUtils.removeTrailingSlash(servletRequest.getRequestURL().toString());
String servletPath = UrlUtils.removeTrailingSlash(servletRequest.getServletPath());

if (pathPrefix != null && servletPath.startsWith(pathPrefix)) {
// harden again invalid servlet paths (e.g. in case of filters)
servletPath = pathPrefix;
} else if (servletPath.isEmpty()) {
}
if (servletPath.isEmpty()) {
return UrlUtils.removeTrailingSlash(requestUrl);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
apply plugin: 'java'

apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE'
}
}

dependencies {

compile project(':crnk-servlet')
compile project(':crnk-setup:crnk-setup-spring')
compileOnly project(':crnk-jpa')
compileOnly project(':crnk-validation')
compileOnly project(':crnk-home')
Expand All @@ -12,14 +20,14 @@ dependencies {
compileOnly project(':crnk-ui')
compileOnly project(':crnk-client')

compileOnly 'org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE'
compileOnly 'org.springframework.boot:spring-boot-configuration-processor:1.5.8.RELEASE'
compileOnly 'org.springframework.boot:spring-boot-starter-actuator:1.5.8.RELEASE'
compileOnly 'org.springframework.security:spring-security-core:4.2.1.RELEASE'
compileOnly 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.springframework.boot:spring-boot-configuration-processor'
compileOnly 'org.springframework.boot:spring-boot-starter-actuator'
compileOnly 'org.springframework.security:spring-security-core'
compileOnly 'org.springframework.cloud:spring-cloud-starter-sleuth:1.3.0.RELEASE'
compileOnly 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'

compileOnly group: 'org.springframework', name: 'spring-orm', version: '4.3.4.RELEASE'
compileOnly(group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.0.Final')
compileOnly 'org.springframework:spring-orm'

testCompile project(':crnk-jpa')
testCompile project(':crnk-jpa')
Expand All @@ -35,20 +43,20 @@ dependencies {
testCompile 'javax.el:javax.el-api:2.2.4'
testCompile 'org.glassfish.web:javax.el:2.2.6'

testCompile 'org.springframework.boot:spring-boot-starter-data-jpa:1.5.8.RELEASE'
testCompile 'org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE'
testCompile 'org.springframework.boot:spring-boot-starter-test:1.5.8.RELEASE'
testCompile 'org.springframework.boot:spring-boot-starter-actuator:1.5.8.RELEASE'
testCompile 'org.springframework.boot:spring-boot-starter-data-jpa'
testCompile 'org.springframework.boot:spring-boot-starter-web'
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'org.springframework.boot:spring-boot-starter-actuator'
testCompile 'org.springframework.cloud:spring-cloud-starter-sleuth:1.3.0.RELEASE'

testCompile 'org.hibernate:hibernate-core:5.1.0.Final'
testCompile 'org.hibernate:hibernate-entitymanager:5.1.0.Final'
testCompile 'com.h2database:h2:1.4.195'
testCompile 'org.hibernate:hibernate-core'
testCompile 'org.hibernate:hibernate-entitymanager'
testCompile 'com.h2database:h2'

testCompile group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '1.5.8.RELEASE'
testCompile group: 'org.springframework', name: 'spring-orm', version: '4.3.4.RELEASE'
testCompile group: 'org.springframework.security', name: 'spring-security-core', version: '4.2.1.RELEASE'
testCompile group: 'net.javacrumbs.json-unit', name: 'json-unit-fluent', version: '1.5.3'
testCompile 'org.springframework.boot:spring-boot-configuration-processor'
testCompile 'org.springframework:spring-orm'
testCompile 'org.springframework.security:spring-security-core'
testCompile 'net.javacrumbs.json-unit:json-unit-fluent:1.5.3'
}


Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import io.crnk.servlet.internal.ServletRequestContext;
import io.crnk.spring.boot.CrnkSpringBootProperties;

/**
* @deprecated use CrnkFilter
*/
@Priority(20)
@Deprecated
public class SpringCrnkFilter implements Filter {

private final CrnkSpringBootProperties properties;

private CrnkBoot boot;

private FilterConfig filterConfig;
Expand All @@ -32,7 +34,6 @@ public class SpringCrnkFilter implements Filter {

public SpringCrnkFilter(CrnkBoot boot, CrnkSpringBootProperties properties) {
this.boot = boot;
this.properties = properties;
}

@Override
Expand Down Expand Up @@ -65,7 +66,7 @@ public void setDefaultCharacterEncoding(String defaultCharacterEncoding) {
}

private boolean matchesPrefix(HttpServletRequest request) {
String pathPrefix = UrlUtils.removeLeadingSlash(properties.getPathPrefix());
String pathPrefix = UrlUtils.removeLeadingSlash(boot.getWebPathPrefix());
String path = UrlUtils.removeLeadingSlash(request.getRequestURI().substring(request.getContextPath().length()));
return pathPrefix == null || path.startsWith(pathPrefix);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("crnk")
@Deprecated
public class CrnkSpringBootProperties {

private boolean enabled = true;
Expand Down

0 comments on commit 8b95571

Please sign in to comment.