From bb7fdfd4b873d94b4a6054bc6da14facb0c1cfc6 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Wed, 15 Nov 2017 11:28:29 -0600 Subject: [PATCH] Split Spring Boot autoconfiguration for Web MVC to a separate starter dependency. Rename the core library from spring-cloud-cloudfoundry-service-broker to spring-cloud-open-service-broker. --- build.gradle | 214 +++++++++--------- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 51017 -> 54706 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 110 ++++----- gradlew.bat | 14 +- settings.gradle | 7 + spring-cloud-open-service-broker/build.gradle | 31 +++ .../controller/BaseController.java | 0 .../controller/CatalogController.java | 7 +- .../ServiceInstanceBindingController.java | 0 .../controller/ServiceInstanceController.java | 4 +- .../ServiceBrokerApiVersionException.java | 2 +- .../ServiceBrokerAsyncRequiredException.java | 0 .../exception/ServiceBrokerException.java | 2 +- ...rviceBrokerInvalidParametersException.java | 0 ...erviceDefinitionDoesNotExistException.java | 6 +- ...eInstanceBindingDoesNotExistException.java | 0 ...ServiceInstanceBindingExistsException.java | 4 +- .../ServiceInstanceDoesNotExistException.java | 6 +- .../ServiceInstanceExistsException.java | 4 +- ...ceInstanceUpdateNotSupportedException.java | 0 ...ncParameterizedServiceInstanceRequest.java | 0 .../model/AsyncRequiredErrorMessage.java | 6 +- .../model/AsyncServiceInstanceRequest.java | 2 +- .../model/AsyncServiceInstanceResponse.java | 0 .../servicebroker/model/BindResource.java | 0 .../servicebroker/model/BrokerApiVersion.java | 79 +++++++ .../cloud/servicebroker/model/Catalog.java | 3 +- .../model/CloudFoundryContext.java | 0 .../cloud/servicebroker/model/Context.java | 0 ...eateServiceInstanceAppBindingResponse.java | 2 +- .../CreateServiceInstanceBindingRequest.java | 4 +- .../CreateServiceInstanceBindingResponse.java | 2 +- .../model/CreateServiceInstanceRequest.java | 2 +- .../model/CreateServiceInstanceResponse.java | 0 ...teServiceInstanceRouteBindingResponse.java | 2 +- .../servicebroker/model/DashboardClient.java | 0 .../DeleteServiceInstanceBindingRequest.java | 0 .../model/DeleteServiceInstanceRequest.java | 0 .../model/DeleteServiceInstanceResponse.java | 0 .../model/EmptyListSerializer.java | 0 .../model/EmptyMapSerializer.java | 0 .../servicebroker/model/ErrorMessage.java | 2 +- .../model/GetLastServiceOperationRequest.java | 0 .../GetLastServiceOperationResponse.java | 0 .../model/KubernetesContext.java | 0 .../servicebroker/model/MethodSchema.java | 0 .../servicebroker/model/OperationState.java | 0 .../cloud/servicebroker/model/Plan.java | 0 .../cloud/servicebroker/model/Schemas.java | 0 .../model/ServiceBindingResource.java | 0 .../model/ServiceBindingSchema.java | 0 .../model/ServiceBrokerRequest.java | 0 .../model/ServiceDefinition.java | 0 .../model/ServiceDefinitionRequires.java | 0 .../servicebroker/model/ServiceInstance.java | 36 +-- .../model/ServiceInstanceBinding.java | 10 +- .../model/ServiceInstanceSchema.java | 0 .../model/SharedVolumeDevice.java | 0 .../model/UpdateServiceInstanceRequest.java | 0 .../model/UpdateServiceInstanceResponse.java | 0 .../servicebroker/model/VolumeDevice.java | 0 .../servicebroker/model/VolumeMount.java | 0 .../service/BeanCatalogService.java | 8 +- .../servicebroker/service/CatalogService.java | 4 +- ...BindableServiceInstanceBindingService.java | 0 .../ServiceInstanceBindingService.java | 2 +- .../service/ServiceInstanceService.java | 2 +- ...rameterizedServiceInstanceRequestTest.java | 2 +- ...eateServiceInstanceBindingRequestTest.java | 3 +- .../cloud/servicebroker/model/PlanTest.java | 0 .../model/fixture/CatalogFixture.java | 0 .../model/fixture/ContextFixture.java | 0 .../model/fixture/DataFixture.java | 0 .../model/fixture/ParametersFixture.java | 0 .../model/fixture/PlanFixture.java | 0 .../model/fixture/ServiceFixture.java | 6 +- .../ServiceInstanceBindingFixture.java | 0 .../model/fixture/ServiceInstanceFixture.java | 0 .../service}/BeanCatalogServiceTest.java | 21 +- .../resources/bindRequestWithAppGuid.json | 0 .../test/resources/bindRequestWithRoute.json | 0 .../createRequestWithCloudFoundryContext.json | 0 .../createRequestWithCustomContext.json | 0 .../createRequestWithKubernetesContext.json | 0 .../build.gradle | 31 +++ .../ApiVersionAutoConfiguration.java | 62 +++++ .../ApiVersionWebMvcConfigurerAdapter.java | 43 ++++ .../ServiceBrokerAutoConfiguration.java | 60 +++++ .../ServiceBrokerWebMvcAutoConfiguration.java | 62 +++++ .../interceptor/ApiVersionInterceptor.java | 79 +++++++ .../main/resources/META-INF/spring.factories | 4 + .../CatalogControllerIntegrationTest.java | 38 ++-- .../ControllerIntegrationTest.java | 21 +- ...tanceBindingControllerIntegrationTest.java | 6 +- ...tanceBindingControllerIntegrationTest.java | 72 +++--- ...ServiceInstanceBindingIntegrationTest.java | 3 +- ...viceInstanceControllerIntegrationTest.java | 63 +++--- .../ApiVersionInterceptorIntegrationTest.java | 23 +- .../ApiVersionInterceptorTest.java | 28 +-- .../config/BrokerApiVersionConfig.java | 14 -- .../ServiceBrokerAutoConfiguration.java | 40 ---- .../config/WebMvcConfiguration.java | 22 -- .../BrokerApiVersionInterceptor.java | 37 --- .../servicebroker/model/BrokerApiVersion.java | 40 ---- src/main/resources/META-INF/spring.factories | 2 - 107 files changed, 841 insertions(+), 524 deletions(-) create mode 100644 settings.gradle create mode 100644 spring-cloud-open-service-broker/build.gradle rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/controller/BaseController.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java (86%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingController.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java (98%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerAsyncRequiredException.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerInvalidParametersException.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java (98%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingDoesNotExistException.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java (98%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java (98%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java (98%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceUpdateNotSupportedException.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java (86%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceResponse.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/BindResource.java (100%) create mode 100644 spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/Catalog.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CloudFoundryContext.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/Context.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceResponse.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/DashboardClient.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceBindingRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceResponse.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/EmptyListSerializer.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/EmptyMapSerializer.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationResponse.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/KubernetesContext.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/MethodSchema.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/OperationState.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/Plan.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/Schemas.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingResource.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingSchema.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceBrokerRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinition.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinitionRequires.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java (91%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java (94%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceSchema.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/SharedVolumeDevice.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceRequest.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceResponse.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/VolumeDevice.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/model/VolumeMount.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/service/NonBindableServiceInstanceBindingService.java (100%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java (99%) rename {src => spring-cloud-open-service-broker/src}/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java (99%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java (97%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java (96%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/PlanTest.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/CatalogFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/ContextFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/DataFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/ParametersFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/PlanFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java (91%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceBindingFixture.java (100%) rename {src => spring-cloud-open-service-broker/src}/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceFixture.java (100%) rename {src/test/java/org/springframework/cloud/servicebroker/service/impl => spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/service}/BeanCatalogServiceTest.java (81%) rename {src => spring-cloud-open-service-broker/src}/test/resources/bindRequestWithAppGuid.json (100%) rename {src => spring-cloud-open-service-broker/src}/test/resources/bindRequestWithRoute.json (100%) rename {src => spring-cloud-open-service-broker/src}/test/resources/createRequestWithCloudFoundryContext.json (100%) rename {src => spring-cloud-open-service-broker/src}/test/resources/createRequestWithCustomContext.json (100%) rename {src => spring-cloud-open-service-broker/src}/test/resources/createRequestWithKubernetesContext.json (100%) create mode 100644 spring-cloud-starter-service-broker-webmvc/build.gradle create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionAutoConfiguration.java create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionWebMvcConfigurerAdapter.java create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerAutoConfiguration.java create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerWebMvcAutoConfiguration.java create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptor.java create mode 100644 spring-cloud-starter-service-broker-webmvc/src/main/resources/META-INF/spring.factories rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/CatalogControllerIntegrationTest.java (92%) rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/ControllerIntegrationTest.java (94%) rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/NonBindableServiceInstanceBindingControllerIntegrationTest.java (91%) rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/ServiceInstanceBindingControllerIntegrationTest.java (91%) rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/ServiceInstanceBindingIntegrationTest.java (96%) rename {src/test/java/org/springframework/cloud/servicebroker/controller => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration}/ServiceInstanceControllerIntegrationTest.java (96%) rename src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorIntegrationTest.java => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorIntegrationTest.java (73%) rename src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorTest.java => spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorTest.java (83%) delete mode 100644 src/main/java/org/springframework/cloud/servicebroker/config/BrokerApiVersionConfig.java delete mode 100644 src/main/java/org/springframework/cloud/servicebroker/config/ServiceBrokerAutoConfiguration.java delete mode 100644 src/main/java/org/springframework/cloud/servicebroker/config/WebMvcConfiguration.java delete mode 100644 src/main/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptor.java delete mode 100644 src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java delete mode 100644 src/main/resources/META-INF/spring.factories diff --git a/build.gradle b/build.gradle index 76442c2a..343e7136 100644 --- a/build.gradle +++ b/build.gradle @@ -1,131 +1,141 @@ apply plugin: 'base' buildscript { - repositories { - mavenCentral() - maven { url 'http://repo.spring.io/plugins-release' } - } - dependencies { - classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7") - classpath("io.spring.gradle:spring-io-plugin:0.0.4.RELEASE") - } + repositories { + mavenCentral() + maven { url 'http://repo.spring.io/plugins-release' } + } + dependencies { + classpath("io.spring.gradle:propdeps-plugin:0.0.10.RELEASE") + classpath("io.spring.gradle:spring-io-plugin:0.0.8.RELEASE") + } } -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'maven' -apply plugin: 'propdeps' -apply plugin: 'propdeps-maven' -apply plugin: 'propdeps-idea' -apply plugin: 'propdeps-eclipse' - -apply from: "${rootProject.projectDir}/publish-maven.gradle" - -if (project.hasProperty('platformVersion')) { - apply plugin: 'spring-io' - - // necessary to resolve the Spring IO versions (which may include snapshots) - repositories { - maven { url "https://repo.spring.io/libs-snapshot" } - } - - dependencyManagement { - springIoTestRuntime { - imports { - mavenBom "io.spring.platform:platform-bom:${platformVersion}" - } - } - } -} - -archivesBaseName = "spring-cloud-cloudfoundry-service-broker" -group = "org.springframework.cloud" -description = "Spring Cloud - Cloud Foundry Service Broker" - ext { - springBootVersion = '1.2.7.RELEASE' - hibernateValidatorVersion = '5.1.0.Final' - jsonPathVersion = '0.9.1' + springVersion = '4.3.12.RELEASE' + springSecurityVersion = '4.2.3.RELEASE' - javadocLinks = [ - 'http://docs.oracle.com/javase/8/docs/api/', - 'http://docs.spring.io/spring/docs/current/javadoc-api/', - ] as String[] + junitVersion = "4.12" + mockitoVersion = "2.7.22" + hamcrestVersion = "1.3" + jsonPathVersion = "2.4.0" + + javadocLinks = [ + 'http://docs.oracle.com/javase/8/docs/api/', + 'http://docs.spring.io/spring/docs/current/javadoc-api/', + ] as String[] } -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +description = "Spring Cloud Service Broker" + +allprojects { + group = "org.springframework.cloud" + + apply plugin: 'java' + apply plugin: 'eclipse' + apply plugin: 'idea' + apply plugin: 'maven' + apply plugin: 'propdeps' + apply plugin: 'propdeps-maven' + apply plugin: 'propdeps-idea' + apply plugin: 'propdeps-eclipse' + + apply from: "${rootProject.projectDir}/publish-maven.gradle" + + if (project.hasProperty('platformVersion')) { + apply plugin: 'spring-io' + + // necessary to resolve the Spring IO versions (which may include snapshots) + repositories { + maven { url "https://repo.spring.io/libs-snapshot" } + } + + dependencyManagement { + springIoTestRuntime { + imports { + mavenBom "io.spring.platform:platform-bom:${platformVersion}" + } + } + } + } -repositories { - mavenCentral() } -dependencies { - compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") - compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}") - compile("org.hibernate:hibernate-validator:${hibernateValidatorVersion}") - compile("commons-beanutils:commons-beanutils:1.9.2") - provided("org.projectlombok:lombok:1.16.6") +subprojects { + sourceCompatibility = 1.8 + targetCompatibility = 1.8 - testCompile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}") - testCompile("com.jayway.jsonpath:json-path:${jsonPathVersion}") + repositories { + mavenCentral() + } } -task testsJar(type: Jar) { - classifier = 'tests' - from sourceSets.test.output -} +configure(rootProject) { + task testsJar(type: Jar) { + classifier = 'tests' + from sourceSets.test.output + } -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource -} + task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource + } -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc -} + task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc + } -task apidocs(type: Javadoc) { - group = "Documentation" - description = "Generates aggregated Javadoc API documentation." - title = "${project.description} ${version} API" - options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED - options.author = true - options.header = rootProject.description - options.links(project.ext.javadocLinks) + task api(type: Javadoc) { + group = "Documentation" + description = "Generates aggregated Javadoc API documentation." + title = "${rootProject.description} ${version} API" - source project.sourceSets.main.allJava + options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED + options.author = true + options.header = rootProject.description + options.links(project.ext.javadocLinks) - classpath = files(project.sourceSets.main.compileClasspath) + source subprojects.collect { project -> + project.sourceSets.main.allJava + } - maxMemory = "1024m" - destinationDir = new File(buildDir, "apidocs") -} + classpath = files(subprojects.collect { project -> + project.sourceSets.main.compileClasspath + }) -task docsZip(type: Zip) { - group = 'Distribution' - classifier = 'docs' - description = "Builds -${classifier} archive containing api and reference." + maxMemory = "1024m" + destinationDir = new File(buildDir, "api") + } - from(apidocs) { - into 'apidocs' - } -} + task docsZip(type: Zip) { + group = 'Distribution' + classifier = 'docs' + description = "Builds -${classifier} archive containing api and reference " + + "for deployment." -artifacts { - archives testsJar - archives sourcesJar - archives javadocJar - archives docsZip -} + from(api) { + into 'api' + } + } -task dist(dependsOn: assemble) { - group = 'Distribution' - description = 'Builds -dist and -docs distribution archives.' + artifacts { + archives docsZip + } + + artifacts { + archives testsJar + archives sourcesJar + archives javadocJar + archives docsZip + } + + task dist(dependsOn: assemble) { + group = 'Distribution' + description = 'Builds -dist and -docs distribution archives.' + } } task wrapper(type: Wrapper) { - gradleVersion = '2.14' + gradleVersion = '3.5' } diff --git a/gradle.properties b/gradle.properties index b118483d..dfe1192e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.3.BUILD-SNAPSHOT +version=2.0.0.BUILD-SNAPSHOT diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index b7612167031001b7b84baf2a959e8ea8ad03c011..7dff28f92613de69f7305397c63298dd45f5d85b 100644 GIT binary patch delta 37080 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 +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282a..f9553162 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..70a128a6 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,7 @@ +rootProject.name = 'spring-cloud-service-broker' + +include ':spring-cloud-open-service-broker' +include ':spring-cloud-starter-service-broker-webmvc' + +project(':spring-cloud-open-service-broker').projectDir = "$rootDir/spring-cloud-open-service-broker" as File +project(':spring-cloud-starter-service-broker-webmvc').projectDir = "$rootDir/spring-cloud-starter-service-broker-webmvc" as File diff --git a/spring-cloud-open-service-broker/build.gradle b/spring-cloud-open-service-broker/build.gradle new file mode 100644 index 00000000..8922de3a --- /dev/null +++ b/spring-cloud-open-service-broker/build.gradle @@ -0,0 +1,31 @@ +description = "Spring Cloud Open Service Broker" + +dependencies { + compile("org.springframework:spring-web:${springVersion}") + compile("org.springframework.security:spring-security-core:${springSecurityVersion}") + compile("com.fasterxml.jackson.core:jackson-databind:2.8.10") + compile("org.hibernate:hibernate-validator:5.3.5.Final") + compile("commons-beanutils:commons-beanutils:1.9.3") + compile("org.slf4j:slf4j-api:1.7.12") + provided("org.projectlombok:lombok:1.16.6") + + testCompile("org.springframework:spring-test:${springVersion}") + + testCompile("junit:junit:${junitVersion}") + testCompile("org.hamcrest:hamcrest-library:${hamcrestVersion}") + testCompile("org.mockito:mockito-core:${mockitoVersion}") + testCompile("com.jayway.jsonpath:json-path:${jsonPathVersion}") +} + +task testsJar(type: Jar) { + classifier = 'tests' + from sourceSets.test.output +} + +configurations { + testOutput +} + +artifacts { + testOutput testsJar +} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/servicebroker/controller/BaseController.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/BaseController.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/controller/BaseController.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/BaseController.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java similarity index 86% rename from src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java index c8e4dcd1..e4b57ccf 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/CatalogController.java @@ -22,12 +22,9 @@ public class CatalogController extends BaseController { super(service); } - @RequestMapping(value = { - "/v2/catalog", - "{cfInstanceId}/v2/catalog" - }, method = RequestMethod.GET) + @RequestMapping(value = {"/v2/catalog", "{cfInstanceId}/v2/catalog"}, method = RequestMethod.GET) public Catalog getCatalog() { - log.debug("getCatalog()"); + log.debug("Retrieving catalog"); return catalogService.getCatalog(); } } diff --git a/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingController.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingController.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingController.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingController.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java similarity index 98% rename from src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java index 9421b418..0198e3b4 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java @@ -39,7 +39,7 @@ import static org.springframework.cloud.servicebroker.model.ServiceBrokerRequest /** * See: http://docs.cloudfoundry.org/services/api.html - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ @@ -50,7 +50,7 @@ public class ServiceInstanceController extends BaseController { private ServiceInstanceService service; @Autowired - public ServiceInstanceController(CatalogService catalogService, ServiceInstanceService serviceInstanceService) { + public ServiceInstanceController(CatalogService catalogService, ServiceInstanceService serviceInstanceService) { super(catalogService); this.service = serviceInstanceService; } diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java index ca413c90..9d6e0d0a 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerApiVersionException.java @@ -13,5 +13,5 @@ public class ServiceBrokerApiVersionException extends RuntimeException { + "expected version=" + expectedVersion + ", provided version = " + providedVersion); } - + } diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerAsyncRequiredException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerAsyncRequiredException.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerAsyncRequiredException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerAsyncRequiredException.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java index dd64a22f..eb97df19 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerException.java @@ -3,7 +3,7 @@ package org.springframework.cloud.servicebroker.exception; /** * General exception for underlying broker errors (like connectivity to the service * being brokered). - * + * * @author sgreenberg@pivotal.io * */ diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerInvalidParametersException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerInvalidParametersException.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerInvalidParametersException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceBrokerInvalidParametersException.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java similarity index 98% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java index 96bb0c3e..8de0139a 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceDefinitionDoesNotExistException.java @@ -2,15 +2,15 @@ package org.springframework.cloud.servicebroker.exception; /** * Thrown to indicate that a request includes a service definition ID does not exist. - * + * * @author sgreenberg@pivotal.io */ public class ServiceDefinitionDoesNotExistException extends RuntimeException { - + private static final long serialVersionUID = -62090827040416788L; public ServiceDefinitionDoesNotExistException(String serviceDefinitionId) { super("Service definition does not exist: id=" + serviceDefinitionId); } - + } \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingDoesNotExistException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingDoesNotExistException.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingDoesNotExistException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingDoesNotExistException.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java similarity index 98% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java index 4c0f014c..2db204bb 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceBindingExistsException.java @@ -2,13 +2,13 @@ package org.springframework.cloud.servicebroker.exception; /** * Thrown to indicate that a duplicate request to bind to a service instance is received. - * + * * @author sgreenberg@pivotal.io */ public class ServiceInstanceBindingExistsException extends RuntimeException { private static final long serialVersionUID = -914571358227517785L; - + public ServiceInstanceBindingExistsException(String serviceInstanceId, String bindingId) { super("Service instance binding already exists: " + "serviceInstanceId=" + serviceInstanceId diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java similarity index 98% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java index f9e9eebf..2bb30411 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceDoesNotExistException.java @@ -2,13 +2,13 @@ package org.springframework.cloud.servicebroker.exception; /** * Thrown to indicate that a request is received for an unknown service instance ID. - * + * * @author sgreenberg@pivotal.io */ public class ServiceInstanceDoesNotExistException extends RuntimeException { - + private static final long serialVersionUID = -1879753092397657116L; - + public ServiceInstanceDoesNotExistException(String serviceInstanceId) { super("Service instance does not exist: id=" + serviceInstanceId); } diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java similarity index 98% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java index e79e19c9..8597225f 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceExistsException.java @@ -2,13 +2,13 @@ package org.springframework.cloud.servicebroker.exception; /** * Thrown to indicate that a duplicate service instance creation request is received. - * + * * @author sgreenberg@pivotal.io */ public class ServiceInstanceExistsException extends RuntimeException { private static final long serialVersionUID = -914571358227517785L; - + public ServiceInstanceExistsException(String serviceInstanceId, String serviceDefinitionId) { super("Service instance with the given ID already exists: " + "serviceInstanceId=" + serviceInstanceId + diff --git a/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceUpdateNotSupportedException.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceUpdateNotSupportedException.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceUpdateNotSupportedException.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/exception/ServiceInstanceUpdateNotSupportedException.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java similarity index 86% rename from src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java index 04f8e239..1d182c51 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncRequiredErrorMessage.java @@ -10,9 +10,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class AsyncRequiredErrorMessage extends ErrorMessage { public final static String ASYNC_REQUIRED_ERROR = "AsyncRequired"; - + /** - * This broker requires asynchronous processing. + * This broker requires asynchronous processing. * * @param description user facing error message. */ @@ -21,7 +21,7 @@ public class AsyncRequiredErrorMessage extends ErrorMessage { } @JsonProperty("error") - public String getError() { + public String getError() { return ASYNC_REQUIRED_ERROR; } } diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java index fe72ada3..3a7283a1 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceRequest.java @@ -21,7 +21,7 @@ public abstract class AsyncServiceInstanceRequest extends ServiceBrokerRequest { * true value indicates that clients do allow asynchronous processing. */ protected boolean asyncAccepted; - + public AsyncServiceInstanceRequest() { } } diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceResponse.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/AsyncServiceInstanceResponse.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/BindResource.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BindResource.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/BindResource.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BindResource.java diff --git a/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java new file mode 100644 index 00000000..cd152c3f --- /dev/null +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.model; + +/** + * + */ +public class BrokerApiVersion { + public final static String DEFAULT_API_VERSION_HEADER = "X-Broker-Api-Version"; + + public final static String API_VERSION_ANY = "*"; + public final static String API_VERSION_CURRENT = "2.13"; + + private final String brokerApiVersionHeader; + + private final String apiVersion; + + /** + * Specify the name of the service broker API version header and the API version supported by the service broker. + * + * @param apiVersionHeader the name of the HTTP header field expected to contain the + * service broker API version of the service broker client + * @param apiVersion the version of the service broker API supported by the broker; a value of + * {@literal null} or {@literal API_VERSION_ANY} will disable API version validation + */ + public BrokerApiVersion(String apiVersionHeader, String apiVersion) { + this.brokerApiVersionHeader = apiVersionHeader; + this.apiVersion = apiVersion; + } + + /** + * Specify the service broker API version supported by the service broker. + * + * @param apiVersion the version of the broker API supported by the broker; a value of {@literal null} + * or {@literal API_VERSION_ANY} will disable API version validation + */ + public BrokerApiVersion(String apiVersion) { + this(DEFAULT_API_VERSION_HEADER, apiVersion); + } + + /** + * Specify that service broker API validation should be disabled. + */ + public BrokerApiVersion() { + this(API_VERSION_ANY); + } + + /** + * Get the service broker API version supported by the service broker. + * + * @return the service broker API version supported by the service broker + */ + public String getApiVersion() { + return apiVersion; + } + + /** + * Get the name of the service broker API version header. + * + * @return the name of the service broker API version header + */ + public String getBrokerApiVersionHeader() { + return brokerApiVersionHeader; + } +} diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java index c13f42da..35a0483b 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Catalog.java @@ -14,7 +14,7 @@ import java.util.List; /** * The catalog of services offered by the service broker. - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ @@ -41,4 +41,3 @@ public class Catalog { this.serviceDefinitions = serviceDefinitions; } } - diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CloudFoundryContext.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CloudFoundryContext.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/CloudFoundryContext.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CloudFoundryContext.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/Context.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Context.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/Context.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Context.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java index c7ef6f18..8cf87c37 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceAppBindingResponse.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * Details of a response to a request to create a new service instance binding for an application. - * + * * @author sgreenberg@pivotal.io * @author Josh Long * @author Scott Frederick diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java index 731eaf4a..ce9b3bd5 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequest.java @@ -15,7 +15,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * Details of a request to bind to a service instance binding. - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ @@ -102,7 +102,7 @@ public class CreateServiceInstanceBindingRequest extends ServiceBrokerRequest { context = null; parameters = null; } - + public CreateServiceInstanceBindingRequest(String serviceDefinitionId, String planId, BindResource bindResource, Context context, Map parameters) { diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java index 45417bf8..d29952a6 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingResponse.java @@ -9,7 +9,7 @@ import lombok.ToString; /** * Details of a response to a service instance binding create request. - * + * * @author Scott Frederick */ @Getter diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java index c4a12191..6be4b30e 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRequest.java @@ -13,7 +13,7 @@ import java.util.Map; /** * Details of a request to create a new service instance. - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceResponse.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceResponse.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java index 06974529..4ad43cd2 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceRouteBindingResponse.java @@ -9,7 +9,7 @@ import lombok.ToString; /** * Details of a response to a request to create a new service instance binding for a route. - * + * * @author Scott Frederick */ @Getter diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/DashboardClient.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DashboardClient.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/DashboardClient.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DashboardClient.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceBindingRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceBindingRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceBindingRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceBindingRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceResponse.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/DeleteServiceInstanceResponse.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/EmptyListSerializer.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/EmptyListSerializer.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/EmptyListSerializer.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/EmptyListSerializer.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/EmptyMapSerializer.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/EmptyMapSerializer.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/EmptyMapSerializer.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/EmptyMapSerializer.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java index 0b98750b..5b14edfa 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ErrorMessage.java @@ -7,7 +7,7 @@ import lombok.ToString; /** * Used to send errors back to the cloud controller. - * + * * @author sgreenberg@pivotal.io */ @Getter diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationResponse.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/GetLastServiceOperationResponse.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/KubernetesContext.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/KubernetesContext.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/KubernetesContext.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/KubernetesContext.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/MethodSchema.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/MethodSchema.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/MethodSchema.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/MethodSchema.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/OperationState.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/OperationState.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/OperationState.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/OperationState.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/Plan.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Plan.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/Plan.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Plan.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/Schemas.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Schemas.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/Schemas.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/Schemas.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingResource.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingResource.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingResource.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingResource.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingSchema.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingSchema.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingSchema.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBindingSchema.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBrokerRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBrokerRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceBrokerRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceBrokerRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinition.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinition.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinition.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinition.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinitionRequires.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinitionRequires.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinitionRequires.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceDefinitionRequires.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java similarity index 91% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java index 7e693644..2211ee76 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstance.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * An instance of a ServiceDefinition. - * + * * @author sgreenberg@pivotal.io * * @deprecated This class is no longer used internally to represent service instances. Implementing brokers should @@ -19,23 +19,23 @@ public class ServiceInstance { @JsonSerialize @JsonProperty("service_instance_id") private String serviceInstanceId; - + @JsonSerialize @JsonProperty("service_id") private String serviceDefinitionId; - + @JsonSerialize @JsonProperty("plan_id") private String planId; - + @JsonSerialize @JsonProperty("organization_guid") private String organizationGuid; - + @JsonSerialize @JsonProperty("space_guid") private String spaceGuid; - + @JsonSerialize @JsonProperty("dashboard_url") private String dashboardUrl; @@ -43,16 +43,16 @@ public class ServiceInstance { @JsonSerialize @JsonProperty("last_operation") private GetLastServiceOperationResponse lastOperation; - + @JsonIgnore private boolean async; - + @SuppressWarnings("unused") private ServiceInstance() {} - + /** - * Create a ServiceInstance from a create request. If fields - * are not present in the request they will remain null in the + * Create a ServiceInstance from a create request. If fields + * are not present in the request they will remain null in the * ServiceInstance. * @param request containing details of ServiceInstance */ @@ -66,10 +66,10 @@ public class ServiceInstance { .withOperationState(OperationState.IN_PROGRESS) .withDescription("Provisioning"); } - + /** - * Create a ServiceInstance from a delete request. If fields - * are not present in the request they will remain null in the + * Create a ServiceInstance from a delete request. If fields + * are not present in the request they will remain null in the * ServiceInstance. * @param request containing details of ServiceInstance */ @@ -81,10 +81,10 @@ public class ServiceInstance { .withOperationState(OperationState.IN_PROGRESS) .withDescription("Deprovisioning"); } - + /** * Create a service instance from an update request. If fields - * are not present in the request they will remain null in the + * are not present in the request they will remain null in the * ServiceInstance. * @param request containing details of ServiceInstance */ @@ -95,7 +95,7 @@ public class ServiceInstance { .withOperationState(OperationState.IN_PROGRESS) .withDescription("Updating"); } - + public String getServiceInstanceId() { return serviceInstanceId; } @@ -146,5 +146,5 @@ public class ServiceInstance { public GetLastServiceOperationResponse getServiceInstanceLastOperation() { return lastOperation; } - + } diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java similarity index 94% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java index a5f77725..be1e58b6 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceBinding.java @@ -5,7 +5,7 @@ import java.util.Map; /** * A binding to a service instance - * + * * @author sgreenberg@pivotal.io * * @deprecated This class is no longer used internally to represent service instance bindings. Implementing brokers should @@ -20,8 +20,8 @@ public class ServiceInstanceBinding { private String syslogDrainUrl; private String appGuid; - public ServiceInstanceBinding(String id, - String serviceInstanceId, + public ServiceInstanceBinding(String id, + String serviceInstanceId, Map credentials, String syslogDrainUrl, String appGuid) { this.id = id; @@ -54,9 +54,9 @@ public class ServiceInstanceBinding { public String getSyslogDrainUrl() { return syslogDrainUrl; } - + public String getAppGuid() { return appGuid; } - + } diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceSchema.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceSchema.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceSchema.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/ServiceInstanceSchema.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/SharedVolumeDevice.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/SharedVolumeDevice.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/SharedVolumeDevice.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/SharedVolumeDevice.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceRequest.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceRequest.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceRequest.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceRequest.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceResponse.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceResponse.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceResponse.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/UpdateServiceInstanceResponse.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/VolumeDevice.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/VolumeDevice.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/VolumeDevice.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/VolumeDevice.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/VolumeMount.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/VolumeMount.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/model/VolumeMount.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/model/VolumeMount.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java index 7f707563..ece34b89 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/BeanCatalogService.java @@ -9,26 +9,26 @@ import org.springframework.beans.factory.annotation.Autowired; /** * An implementation of the CatalogService that allows the Catalog to be specified as a Spring Bean. - * + * * @author sgreenberg@pivotal.io */ public class BeanCatalogService implements CatalogService { private Catalog catalog; private Map serviceDefs = new HashMap(); - + @Autowired public BeanCatalogService(Catalog catalog) { this.catalog = catalog; initializeMap(); } - + private void initializeMap() { for (ServiceDefinition def: catalog.getServiceDefinitions()) { serviceDefs.put(def.getId(), def); } } - + @Override public Catalog getCatalog() { return catalog; diff --git a/src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java index 4955b3fb..72f82857 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/CatalogService.java @@ -5,7 +5,7 @@ import org.springframework.cloud.servicebroker.model.ServiceDefinition; /** * This interface is implemented by service brokers to process requests to retrieve the service catalog. - * + * * @author sgreenberg@pivotal.io */ public interface CatalogService { @@ -24,5 +24,5 @@ public interface CatalogService { * @return the service definition, or null if it doesn't exist */ ServiceDefinition getServiceDefinition(String serviceId); - + } diff --git a/src/main/java/org/springframework/cloud/servicebroker/service/NonBindableServiceInstanceBindingService.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/NonBindableServiceInstanceBindingService.java similarity index 100% rename from src/main/java/org/springframework/cloud/servicebroker/service/NonBindableServiceInstanceBindingService.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/NonBindableServiceInstanceBindingService.java diff --git a/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java index f4a223ad..15373487 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceBindingService.java @@ -10,7 +10,7 @@ import org.springframework.cloud.servicebroker.model.DeleteServiceInstanceBindin /** * This interface is implemented by service brokers to process requests to create and delete service instance bindings. - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ diff --git a/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java similarity index 99% rename from src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java rename to spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java index 4af01498..44a0e701 100644 --- a/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java +++ b/spring-cloud-open-service-broker/src/main/java/org/springframework/cloud/servicebroker/service/ServiceInstanceService.java @@ -16,7 +16,7 @@ import org.springframework.cloud.servicebroker.model.UpdateServiceInstanceRespon /** * This interface is implemented by service brokers to process requests related to provisioning, updating, * and deprovisioning service instances. - * + * * @author sgreenberg@pivotal.io * @author Scott Frederick */ diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java similarity index 97% rename from src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java index 311ff1bb..e4b2ee3c 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java +++ b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/AsyncParameterizedServiceInstanceRequestTest.java @@ -3,7 +3,7 @@ package org.springframework.cloud.servicebroker.model; import org.junit.Test; import org.springframework.cloud.servicebroker.model.fixture.DataFixture; -import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.springframework.cloud.servicebroker.model.CloudFoundryContext.CLOUD_FOUNDRY_PLATFORM; diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java similarity index 96% rename from src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java index 6e9b3523..f3fd7e36 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java +++ b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/CreateServiceInstanceBindingRequestTest.java @@ -3,13 +3,14 @@ package org.springframework.cloud.servicebroker.model; import org.junit.Test; import org.springframework.cloud.servicebroker.model.fixture.DataFixture; -import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.springframework.cloud.servicebroker.model.CloudFoundryContext.CLOUD_FOUNDRY_PLATFORM; import static org.springframework.cloud.servicebroker.model.KubernetesContext.KUBERNETES_PLATFORM; +@SuppressWarnings({"deprecation", "DeprecatedIsStillUsed"}) public class CreateServiceInstanceBindingRequestTest { @Test public void requestWithAppGuidBindingIsRead() { diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/PlanTest.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/PlanTest.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/PlanTest.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/PlanTest.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/CatalogFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/CatalogFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/CatalogFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/CatalogFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ContextFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ContextFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/ContextFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ContextFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/DataFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/DataFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/DataFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/DataFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ParametersFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ParametersFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/ParametersFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ParametersFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/PlanFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/PlanFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/PlanFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/PlanFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java similarity index 91% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java index 8957e730..5b89dfcc 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java +++ b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceFixture.java @@ -9,9 +9,9 @@ public class ServiceFixture { public static ServiceDefinition getSimpleService() { return new ServiceDefinition( - "service-one-id", - "Service One", - "Description for Service One", + "service-one-id", + "Service One", + "Description for Service One", true, PlanFixture.getAllPlans()); } diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceBindingFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceBindingFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceBindingFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceBindingFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceFixture.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceFixture.java similarity index 100% rename from src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceFixture.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/model/fixture/ServiceInstanceFixture.java diff --git a/src/test/java/org/springframework/cloud/servicebroker/service/impl/BeanCatalogServiceTest.java b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/service/BeanCatalogServiceTest.java similarity index 81% rename from src/test/java/org/springframework/cloud/servicebroker/service/impl/BeanCatalogServiceTest.java rename to spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/service/BeanCatalogServiceTest.java index 9d1cc50d..6ad5ee5b 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/service/impl/BeanCatalogServiceTest.java +++ b/spring-cloud-open-service-broker/src/test/java/org/springframework/cloud/servicebroker/service/BeanCatalogServiceTest.java @@ -1,4 +1,4 @@ -package org.springframework.cloud.servicebroker.service.impl; +package org.springframework.cloud.servicebroker.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -8,18 +8,17 @@ import java.util.List; import org.springframework.cloud.servicebroker.model.Catalog; import org.springframework.cloud.servicebroker.model.ServiceDefinition; -import org.springframework.cloud.servicebroker.service.BeanCatalogService; import org.junit.Before; import org.junit.Test; public class BeanCatalogServiceTest { private BeanCatalogService service; - + private Catalog catalog; private ServiceDefinition serviceDefinition; private static final String SVC_DEF_ID = "svc-def-id"; - + @Before public void setup() { serviceDefinition = new ServiceDefinition(SVC_DEF_ID, "Name", "Description", true, null); @@ -27,20 +26,20 @@ public class BeanCatalogServiceTest { catalog = new Catalog(defs); service = new BeanCatalogService(catalog); } - + @Test public void catalogIsReturnedSuccessfully() { assertEquals(catalog, service.getCatalog()); } - - @Test - public void itFindsServiceDefinition() { + + @Test + public void serviceDefinitionIsFound() { assertEquals(serviceDefinition, service.getServiceDefinition(SVC_DEF_ID)); } - + @Test - public void itDoesNotFindServiceDefinition() { + public void serviceDefinitionIsNotFound() { assertNull(service.getServiceDefinition("NOT_THERE")); } - + } diff --git a/src/test/resources/bindRequestWithAppGuid.json b/spring-cloud-open-service-broker/src/test/resources/bindRequestWithAppGuid.json similarity index 100% rename from src/test/resources/bindRequestWithAppGuid.json rename to spring-cloud-open-service-broker/src/test/resources/bindRequestWithAppGuid.json diff --git a/src/test/resources/bindRequestWithRoute.json b/spring-cloud-open-service-broker/src/test/resources/bindRequestWithRoute.json similarity index 100% rename from src/test/resources/bindRequestWithRoute.json rename to spring-cloud-open-service-broker/src/test/resources/bindRequestWithRoute.json diff --git a/src/test/resources/createRequestWithCloudFoundryContext.json b/spring-cloud-open-service-broker/src/test/resources/createRequestWithCloudFoundryContext.json similarity index 100% rename from src/test/resources/createRequestWithCloudFoundryContext.json rename to spring-cloud-open-service-broker/src/test/resources/createRequestWithCloudFoundryContext.json diff --git a/src/test/resources/createRequestWithCustomContext.json b/spring-cloud-open-service-broker/src/test/resources/createRequestWithCustomContext.json similarity index 100% rename from src/test/resources/createRequestWithCustomContext.json rename to spring-cloud-open-service-broker/src/test/resources/createRequestWithCustomContext.json diff --git a/src/test/resources/createRequestWithKubernetesContext.json b/spring-cloud-open-service-broker/src/test/resources/createRequestWithKubernetesContext.json similarity index 100% rename from src/test/resources/createRequestWithKubernetesContext.json rename to spring-cloud-open-service-broker/src/test/resources/createRequestWithKubernetesContext.json diff --git a/spring-cloud-starter-service-broker-webmvc/build.gradle b/spring-cloud-starter-service-broker-webmvc/build.gradle new file mode 100644 index 00000000..9adf8847 --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/build.gradle @@ -0,0 +1,31 @@ +description = "Spring Cloud Service Broker Starter" + +buildscript { + ext { + springBootVersion = "1.5.8.RELEASE" + } + + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + } +} + +apply plugin: 'org.springframework.boot' + +bootRepackage { + enabled = false +} + +dependencies { + compile project(":spring-cloud-open-service-broker") + compile("org.springframework.boot:spring-boot-starter-web") + compile("org.springframework.boot:spring-boot-starter-security") + + testCompile project(path: ":spring-cloud-open-service-broker", configuration: 'testOutput') + testCompile("org.springframework.boot:spring-boot-starter-test") + testCompile("org.mockito:mockito-core:${mockitoVersion}") + testCompile("org.hamcrest:hamcrest-library:${hamcrestVersion}") +} diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionAutoConfiguration.java b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionAutoConfiguration.java new file mode 100644 index 00000000..65edff01 --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionAutoConfiguration.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.webmvc.autoconfig; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.cloud.servicebroker.model.Catalog; +import org.springframework.cloud.servicebroker.service.ServiceInstanceService; +import org.springframework.cloud.servicebroker.webmvc.interceptor.ApiVersionInterceptor; +import org.springframework.cloud.servicebroker.model.BrokerApiVersion; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the service broker API validation. + * Configures support for any service broker API version if a version is not specifically + * configured. + * + * @author Benjamin Ihrig + * @author Scott Frederick + */ +@Configuration +@ConditionalOnWebApplication +@ConditionalOnBean({ Catalog.class, ServiceInstanceService.class }) +@AutoConfigureAfter(WebMvcAutoConfiguration.class) +public class ApiVersionAutoConfiguration { + @Bean + @ConditionalOnMissingBean(BrokerApiVersion.class) + public BrokerApiVersion serviceBrokerApiVersion() { + return new BrokerApiVersion(); + } + + @Bean + public ApiVersionInterceptor serviceBrokerApiVersionInterceptor(BrokerApiVersion brokerApiVersion) { + return new ApiVersionInterceptor(brokerApiVersion); + } + + @Bean + public ApiVersionWebMvcConfigurerAdapter serviceBrokerWebMvcConfigurerAdapter( + ApiVersionInterceptor apiVersionInterceptor) { + return new ApiVersionWebMvcConfigurerAdapter( + apiVersionInterceptor); + } +} \ No newline at end of file diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionWebMvcConfigurerAdapter.java b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionWebMvcConfigurerAdapter.java new file mode 100644 index 00000000..426421af --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ApiVersionWebMvcConfigurerAdapter.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.webmvc.autoconfig; + +import org.springframework.cloud.servicebroker.webmvc.interceptor.ApiVersionInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * {@link WebMvcConfigurerAdapter} that configures checking for an appropriate service broker API version. + * + * @author Scott Frederick + * @author Benjamin Ihrig + */ +public class ApiVersionWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { + private static final String V2_API_PATH_PATTERN = "/v2/**"; + + private final ApiVersionInterceptor apiVersionInterceptor; + + ApiVersionWebMvcConfigurerAdapter(ApiVersionInterceptor apiVersionInterceptor) { + this.apiVersionInterceptor = apiVersionInterceptor; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(apiVersionInterceptor).addPathPatterns(V2_API_PATH_PATTERN); + } +} \ No newline at end of file diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerAutoConfiguration.java b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerAutoConfiguration.java new file mode 100644 index 00000000..9daf0d60 --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerAutoConfiguration.java @@ -0,0 +1,60 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.webmvc.autoconfig; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.cloud.servicebroker.model.Catalog; +import org.springframework.cloud.servicebroker.service.BeanCatalogService; +import org.springframework.cloud.servicebroker.service.CatalogService; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; +import org.springframework.cloud.servicebroker.service.NonBindableServiceInstanceBindingService; +import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; +import org.springframework.cloud.servicebroker.service.ServiceInstanceService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the service broker implementation beans. + * + * Provides a default {@link CatalogService} bean if a {@link Catalog} bean is provided. + * + * Provides a {@link NonBindableServiceInstanceBindingService} if a {@link ServiceInstanceBindingService} + * is not provided, indicating that the service broker provides no bindable services. + * + * @author Scott Frederick + */ +@Configuration +@ConditionalOnWebApplication +@ConditionalOnBean({ Catalog.class, ServiceInstanceService.class }) +@AutoConfigureAfter(WebMvcAutoConfiguration.class) +public class ServiceBrokerAutoConfiguration { + @Bean + @ConditionalOnMissingBean(CatalogService.class) + public CatalogService beanCatalogService(Catalog catalog) { + return new BeanCatalogService(catalog); + } + + @Bean + @ConditionalOnMissingBean(ServiceInstanceBindingService.class) + public ServiceInstanceBindingService nonBindableServiceInstanceBindingService() { + return new NonBindableServiceInstanceBindingService(); + } +} \ No newline at end of file diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerWebMvcAutoConfiguration.java b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerWebMvcAutoConfiguration.java new file mode 100644 index 00000000..357f5fed --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/autoconfig/ServiceBrokerWebMvcAutoConfiguration.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.webmvc.autoconfig; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.cloud.servicebroker.controller.CatalogController; +import org.springframework.cloud.servicebroker.controller.ServiceInstanceBindingController; +import org.springframework.cloud.servicebroker.controller.ServiceInstanceController; +import org.springframework.cloud.servicebroker.model.Catalog; +import org.springframework.cloud.servicebroker.service.CatalogService; +import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; +import org.springframework.cloud.servicebroker.service.ServiceInstanceService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for the service broker REST API endpoints. + * + * @author Benjamin Ihrig + */ +@Configuration +@ConditionalOnWebApplication +@ConditionalOnBean({ Catalog.class, ServiceInstanceService.class }) +@AutoConfigureAfter(ServiceBrokerAutoConfiguration.class) +public class ServiceBrokerWebMvcAutoConfiguration { + + @Bean + public CatalogController catalogController(CatalogService catalogService) { + return new CatalogController(catalogService); + } + + @Bean + public ServiceInstanceController serviceInstanceController( + CatalogService catalogService, + ServiceInstanceService serviceInstanceService) { + return new ServiceInstanceController(catalogService, serviceInstanceService); + } + + @Bean + public ServiceInstanceBindingController serviceInstanceBindingController( + CatalogService catalogService, + ServiceInstanceBindingService serviceInstanceBindingService) { + return new ServiceInstanceBindingController(catalogService, serviceInstanceBindingService); + } +} diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptor.java b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptor.java new file mode 100644 index 00000000..1511dab8 --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptor.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed 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 org.springframework.cloud.servicebroker.webmvc.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.cloud.servicebroker.exception.ServiceBrokerApiVersionException; +import org.springframework.cloud.servicebroker.model.BrokerApiVersion; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +/** + * {@link HandlerInterceptor} that inspects the service broker API version passed in all request headers + * and compares it to the API version supported by the broker. + * + * @author Scott Frederick + */ +public class ApiVersionInterceptor extends HandlerInterceptorAdapter { + + private final BrokerApiVersion version; + + /** + * Construct an interceptor that disables API version validation. + */ + public ApiVersionInterceptor() { + this(null); + } + + /** + * Construct an interceptor that validates the API version passed in request headers to the + * configured version. + * + * @param version the API version supported by the broker. + */ + public ApiVersionInterceptor(BrokerApiVersion version) { + this.version = version; + } + + /** + * Compares the service broker API version header to the supported version. + * + * @param request {@inheritDoc} + * @param response {@inheritDoc} + * @param handler {@inheritDoc} + * @throws ServiceBrokerApiVersionException if the API version header value does not match the version + * supported by the broker + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws ServiceBrokerApiVersionException { + if (version != null && !anyVersionAllowed()) { + String apiVersion = request.getHeader(version.getBrokerApiVersionHeader()); + if (!version.getApiVersion().equals(apiVersion)) { + throw new ServiceBrokerApiVersionException(version.getApiVersion(), apiVersion); + } + } + return true; + } + + private boolean anyVersionAllowed() { + return BrokerApiVersion.API_VERSION_ANY.equals(version.getApiVersion()); + } + +} diff --git a/spring-cloud-starter-service-broker-webmvc/src/main/resources/META-INF/spring.factories b/spring-cloud-starter-service-broker-webmvc/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..bd505b25 --- /dev/null +++ b/spring-cloud-starter-service-broker-webmvc/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.servicebroker.webvmc.autoconfig.ServiceBrokerAutoConfiguration,\ +org.springframework.cloud.servicebroker.webvmc.autoconfig.ServiceBrokerWebMvcAutoConfiguration,\ +org.springframework.cloud.servicebroker.webvmc.autoconfig.ApiVersionAutoConfiguration diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/CatalogControllerIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/CatalogControllerIntegrationTest.java similarity index 92% rename from src/test/java/org/springframework/cloud/servicebroker/controller/CatalogControllerIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/CatalogControllerIntegrationTest.java index c50c59f5..5d33e699 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/CatalogControllerIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/CatalogControllerIntegrationTest.java @@ -1,33 +1,37 @@ -package org.springframework.cloud.servicebroker.controller; +package org.springframework.cloud.servicebroker.webmvc.integration; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.servicebroker.controller.CatalogController; import org.springframework.cloud.servicebroker.model.Catalog; import org.springframework.cloud.servicebroker.model.Plan; import org.springframework.cloud.servicebroker.model.ServiceDefinition; import org.springframework.cloud.servicebroker.model.fixture.PlanFixture; import org.springframework.cloud.servicebroker.model.fixture.ServiceFixture; import org.springframework.cloud.servicebroker.service.CatalogService; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.hamcrest.Matchers.*; -import static org.hamcrest.core.IsNot.not; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.collection.IsEmptyCollection.empty; +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.mockito.Mockito.when; import static org.springframework.cloud.servicebroker.model.ServiceDefinitionRequires.SERVICE_REQUIRES_ROUTE_FORWARDING; import static org.springframework.cloud.servicebroker.model.ServiceDefinitionRequires.SERVICE_REQUIRES_SYSLOG_DRAIN; import static org.springframework.cloud.servicebroker.model.fixture.CatalogFixture.getCatalog; import static org.springframework.cloud.servicebroker.model.fixture.CatalogFixture.getCatalogWithRequires; -import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -67,7 +71,7 @@ public class CatalogControllerIntegrationTest { .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.services.", hasSize(1))) + .andExpect(jsonPath("$.services", hasSize(1))) .andExpect(jsonPath("$.services[*].id", contains(service.getId()))) .andExpect(jsonPath("$.services[*].name", contains(service.getName()))) .andExpect(jsonPath("$.services[*].description", contains(service.getDescription()))) @@ -98,7 +102,7 @@ public class CatalogControllerIntegrationTest { .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.services.", hasSize(1))) + .andExpect(jsonPath("$.services", hasSize(1))) .andExpect(jsonPath("$.services[*].id", contains(service.getId()))) .andExpect(jsonPath("$.services[*].name", contains(service.getName()))) .andExpect(jsonPath("$.services[*].description", contains(service.getDescription()))) @@ -133,7 +137,7 @@ public class CatalogControllerIntegrationTest { .andDo(print()) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.services.", hasSize(1))) + .andExpect(jsonPath("$.services", hasSize(1))) .andExpect(jsonPath("$.services[*].id", contains(service.getId()))) .andExpect(jsonPath("$.services[*].name", contains(service.getName()))) .andExpect(jsonPath("$.services[*].description", contains(service.getDescription()))) diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/ControllerIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ControllerIntegrationTest.java similarity index 94% rename from src/test/java/org/springframework/cloud/servicebroker/controller/ControllerIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ControllerIntegrationTest.java index a92d9fae..d5fbbb91 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/ControllerIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ControllerIntegrationTest.java @@ -1,17 +1,18 @@ -package org.springframework.cloud.servicebroker.controller; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.cloud.servicebroker.model.fixture.ServiceFixture; -import org.springframework.cloud.servicebroker.service.CatalogService; -import org.mockito.Mock; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; -import org.springframework.security.crypto.codec.Base64; +package org.springframework.cloud.servicebroker.webmvc.integration; import java.util.HashMap; import java.util.Map; -import static org.mockito.Matchers.eq; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.mockito.Mock; + +import org.springframework.cloud.servicebroker.model.fixture.ServiceFixture; +import org.springframework.cloud.servicebroker.service.CatalogService; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.security.crypto.codec.Base64; + +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; public abstract class ControllerIntegrationTest { diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/NonBindableServiceInstanceBindingControllerIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/NonBindableServiceInstanceBindingControllerIntegrationTest.java similarity index 91% rename from src/test/java/org/springframework/cloud/servicebroker/controller/NonBindableServiceInstanceBindingControllerIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/NonBindableServiceInstanceBindingControllerIntegrationTest.java index d3be4a9b..9715223a 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/NonBindableServiceInstanceBindingControllerIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/NonBindableServiceInstanceBindingControllerIntegrationTest.java @@ -1,9 +1,11 @@ -package org.springframework.cloud.servicebroker.controller; +package org.springframework.cloud.servicebroker.webmvc.integration; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; + +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.cloud.servicebroker.controller.ServiceInstanceBindingController; import org.springframework.cloud.servicebroker.model.fixture.DataFixture; import org.springframework.cloud.servicebroker.service.NonBindableServiceInstanceBindingService; import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingControllerIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingControllerIntegrationTest.java similarity index 91% rename from src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingControllerIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingControllerIntegrationTest.java index 17c6d22b..a50a56b4 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingControllerIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingControllerIntegrationTest.java @@ -1,36 +1,36 @@ -package org.springframework.cloud.servicebroker.controller; +package org.springframework.cloud.servicebroker.webmvc.integration; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.servicebroker.controller.ServiceInstanceBindingController; import org.springframework.cloud.servicebroker.exception.ServiceInstanceBindingDoesNotExistException; import org.springframework.cloud.servicebroker.exception.ServiceInstanceBindingExistsException; import org.springframework.cloud.servicebroker.exception.ServiceInstanceDoesNotExistException; -import org.springframework.cloud.servicebroker.model.CreateServiceInstanceBindingRequest; import org.springframework.cloud.servicebroker.model.CreateServiceInstanceAppBindingResponse; +import org.springframework.cloud.servicebroker.model.CreateServiceInstanceBindingRequest; import org.springframework.cloud.servicebroker.model.CreateServiceInstanceRouteBindingResponse; import org.springframework.cloud.servicebroker.model.DeleteServiceInstanceBindingRequest; import org.springframework.cloud.servicebroker.model.SharedVolumeDevice; import org.springframework.cloud.servicebroker.model.VolumeMount; -import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.servicebroker.model.fixture.DataFixture; import org.springframework.cloud.servicebroker.model.fixture.ServiceInstanceBindingFixture; +import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -45,10 +45,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInstanceBindingIntegrationTest { private MockMvc mockMvc; - + @InjectMocks private ServiceInstanceBindingController controller; - + @Mock private ServiceInstanceBindingService serviceInstanceBindingService; @@ -77,8 +77,8 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .andExpect(jsonPath("$.credentials.uri", is(createResponse.getCredentials().get("uri")))) .andExpect(jsonPath("$.credentials.username", is(createResponse.getCredentials().get("username")))) .andExpect(jsonPath("$.credentials.password", is(createResponse.getCredentials().get("password")))) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) - .andExpect(jsonPath("$.route_service_url", nullValue())); + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) + .andExpect(jsonPath("$.route_service_url").doesNotExist()); CreateServiceInstanceBindingRequest actualRequest = verifyCreateBinding(); assertNull(actualRequest.getCfInstanceId()); @@ -106,8 +106,8 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .andExpect(jsonPath("$.credentials.uri", is(createResponse.getCredentials().get("uri")))) .andExpect(jsonPath("$.credentials.username", is(createResponse.getCredentials().get("username")))) .andExpect(jsonPath("$.credentials.password", is(createResponse.getCredentials().get("password")))) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) - .andExpect(jsonPath("$.route_service_url", nullValue())); + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) + .andExpect(jsonPath("$.route_service_url").doesNotExist()); CreateServiceInstanceBindingRequest actualRequest = verifyCreateBinding(); assertEquals(CF_INSTANCE_ID, actualRequest.getCfInstanceId()); @@ -135,9 +135,9 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .andExpect(jsonPath("$.credentials.uri", is(createResponse.getCredentials().get("uri")))) .andExpect(jsonPath("$.credentials.username", is(createResponse.getCredentials().get("username")))) .andExpect(jsonPath("$.credentials.password", is(createResponse.getCredentials().get("password")))) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) - .andExpect(jsonPath("$.volume_mounts", nullValue())) - .andExpect(jsonPath("$.route_service_url", nullValue())); + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) + .andExpect(jsonPath("$.volume_mounts").doesNotExist()) + .andExpect(jsonPath("$.route_service_url").doesNotExist()); } @Test @@ -155,9 +155,9 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.credentials", nullValue())) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) - .andExpect(jsonPath("$.volume_mounts", nullValue())) + .andExpect(jsonPath("$.credentials").doesNotExist()) + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) + .andExpect(jsonPath("$.volume_mounts").doesNotExist()) .andExpect(jsonPath("$.route_service_url", is(response.getRouteServiceUrl()))); } @@ -178,9 +178,9 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.credentials", nullValue())) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) - .andExpect(jsonPath("$.volume_mounts", nullValue())) + .andExpect(jsonPath("$.credentials").doesNotExist()) + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) + .andExpect(jsonPath("$.volume_mounts").doesNotExist()) .andExpect(jsonPath("$.route_service_url", is(response.getRouteServiceUrl()))); } @@ -202,8 +202,8 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .andExpect(jsonPath("$.credentials.username", is(response.getCredentials().get("username")))) .andExpect(jsonPath("$.credentials.password", is(response.getCredentials().get("password")))) .andExpect(jsonPath("$.syslog_drain_url", is(response.getSyslogDrainUrl()))) - .andExpect(jsonPath("$.volume_mounts", nullValue())) - .andExpect(jsonPath("$.route_service_url", nullValue())); + .andExpect(jsonPath("$.volume_mounts").doesNotExist()) + .andExpect(jsonPath("$.route_service_url").doesNotExist()); } @Test @@ -223,8 +223,8 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.credentials", nullValue())) - .andExpect(jsonPath("$.syslog_drain_url", nullValue())) + .andExpect(jsonPath("$.credentials").doesNotExist()) + .andExpect(jsonPath("$.syslog_drain_url").doesNotExist()) .andExpect(jsonPath("$.volume_mounts[0].driver", is(volumeMount.getDriver()))) .andExpect(jsonPath("$.volume_mounts[0].container_dir", is(volumeMount.getContainerDir()))) .andExpect(jsonPath("$.volume_mounts[0].mode", is(volumeMount.getMode().toString()))) @@ -363,7 +363,7 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst @Test public void deleteBindingWithUnknownBindingIdFails() throws Exception { - Mockito.doThrow(new ServiceInstanceBindingDoesNotExistException(deleteRequest.getBindingId())) + doThrow(new ServiceInstanceBindingDoesNotExistException(deleteRequest.getBindingId())) .when(serviceInstanceBindingService).deleteServiceInstanceBinding(eq(deleteRequest)); setupCatalogService(deleteRequest.getServiceDefinitionId()); @@ -388,13 +388,13 @@ public class ServiceInstanceBindingControllerIntegrationTest extends ServiceInst private CreateServiceInstanceBindingRequest verifyCreateBinding() { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CreateServiceInstanceBindingRequest.class); - Mockito.verify(serviceInstanceBindingService).createServiceInstanceBinding(argumentCaptor.capture()); + verify(serviceInstanceBindingService).createServiceInstanceBinding(argumentCaptor.capture()); return argumentCaptor.getValue(); } private DeleteServiceInstanceBindingRequest verifyDeleteBinding() { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(DeleteServiceInstanceBindingRequest.class); - Mockito.verify(serviceInstanceBindingService).deleteServiceInstanceBinding(argumentCaptor.capture()); + verify(serviceInstanceBindingService).deleteServiceInstanceBinding(argumentCaptor.capture()); return argumentCaptor.getValue(); } } diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingIntegrationTest.java similarity index 96% rename from src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingIntegrationTest.java index b059321b..d8fc1679 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceBindingIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceBindingIntegrationTest.java @@ -1,6 +1,7 @@ -package org.springframework.cloud.servicebroker.controller; +package org.springframework.cloud.servicebroker.webmvc.integration; import org.junit.Before; + import org.springframework.cloud.servicebroker.model.CreateServiceInstanceBindingRequest; import org.springframework.cloud.servicebroker.model.DeleteServiceInstanceBindingRequest; import org.springframework.cloud.servicebroker.model.fixture.ServiceInstanceBindingFixture; diff --git a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceControllerIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceControllerIntegrationTest.java similarity index 96% rename from src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceControllerIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceControllerIntegrationTest.java index 8b7fb8bd..69478de7 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceControllerIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/integration/ServiceInstanceControllerIntegrationTest.java @@ -1,22 +1,15 @@ -package org.springframework.cloud.servicebroker.controller; +package org.springframework.cloud.servicebroker.webmvc.integration; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.servicebroker.model.ServiceBrokerRequest.API_INFO_LOCATION_HEADER; -import static org.springframework.cloud.servicebroker.model.ServiceBrokerRequest.ORIGINATING_IDENTITY_HEADER; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import org.junit.*; +import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.servicebroker.controller.ServiceInstanceController; import org.springframework.cloud.servicebroker.exception.ServiceBrokerAsyncRequiredException; import org.springframework.cloud.servicebroker.exception.ServiceBrokerInvalidParametersException; import org.springframework.cloud.servicebroker.exception.ServiceInstanceDoesNotExistException; @@ -41,6 +34,24 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.util.UriComponentsBuilder; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.StringContains.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.springframework.cloud.servicebroker.model.ServiceBrokerRequest.API_INFO_LOCATION_HEADER; +import static org.springframework.cloud.servicebroker.model.ServiceBrokerRequest.ORIGINATING_IDENTITY_HEADER; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @RunWith(MockitoJUnitRunner.class) public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrationTest { @@ -226,7 +237,7 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.error", org.hamcrest.Matchers.is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) + .andExpect(jsonPath("$.error", is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) .andExpect(jsonPath("$.description", is("async required description"))); } @@ -248,9 +259,6 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat @Test public void createServiceInstanceWithInvalidFieldsFails() throws Exception { - when(serviceInstanceService.createServiceInstance(eq(syncCreateRequest))) - .thenReturn(syncCreateResponse); - setupCatalogService(syncCreateRequest.getServiceDefinitionId()); String body = DataFixture.toJson(syncCreateRequest); @@ -267,9 +275,6 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat @Test public void createServiceInstanceWithMissingFieldsFails() throws Exception { - when(serviceInstanceService.createServiceInstance(any(CreateServiceInstanceRequest.class))) - .thenReturn(syncCreateResponse); - String body = "{}"; mockMvc.perform(put(buildUrl(syncCreateRequest, false)) @@ -286,9 +291,6 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat @Test public void createServiceInstanceWithMissingIdentityPropertiesFails() throws Exception { - when(serviceInstanceService.createServiceInstance(eq(syncCreateRequest))) - .thenReturn(syncCreateResponse); - setupCatalogService(syncCreateRequest.getServiceDefinitionId()); mockMvc.perform(put(buildUrl(syncCreateRequest, false)) @@ -304,9 +306,6 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat @Test public void createServiceInstanceWithMalformedIdentityPropertiesFails() throws Exception { - when(serviceInstanceService.createServiceInstance(eq(syncCreateRequest))) - .thenReturn(syncCreateResponse); - setupCatalogService(syncCreateRequest.getServiceDefinitionId()); mockMvc.perform(put(buildUrl(syncCreateRequest, false)) @@ -416,7 +415,7 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat .header(API_INFO_LOCATION_HEADER, API_INFO_LOCATION) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.error", org.hamcrest.Matchers.is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) + .andExpect(jsonPath("$.error", is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) .andExpect(jsonPath("$.description", is("async required description"))); } @@ -497,7 +496,7 @@ public class ServiceInstanceControllerIntegrationTest extends ControllerIntegrat .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isUnprocessableEntity()) - .andExpect(jsonPath("$.error", org.hamcrest.Matchers.is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) + .andExpect(jsonPath("$.error", is(AsyncRequiredErrorMessage.ASYNC_REQUIRED_ERROR))) .andExpect(jsonPath("$.description", is("async required description"))); } diff --git a/src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorIntegrationTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorIntegrationTest.java similarity index 73% rename from src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorIntegrationTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorIntegrationTest.java index cf201f81..2c6b8c38 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorIntegrationTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorIntegrationTest.java @@ -1,11 +1,11 @@ -package org.springframework.cloud.servicebroker.interceptor; +package org.springframework.cloud.servicebroker.webmvc.interceptor; import static org.hamcrest.Matchers.containsString; -import static org.springframework.cloud.servicebroker.model.BrokerApiVersion.DEFAULT_API_VERSION_HEADER; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import org.mockito.junit.MockitoJUnitRunner; import org.springframework.cloud.servicebroker.controller.CatalogController; import org.springframework.cloud.servicebroker.model.BrokerApiVersion; import org.springframework.cloud.servicebroker.service.CatalogService; @@ -13,14 +13,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @RunWith(MockitoJUnitRunner.class) -public class BrokerApiVersionInterceptorIntegrationTest { +public class ApiVersionInterceptorIntegrationTest { private final static String CATALOG_PATH = "/v2/catalog"; @@ -35,23 +34,23 @@ public class BrokerApiVersionInterceptorIntegrationTest { mockWithExpectedVersion().perform(get(CATALOG_PATH) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isPreconditionFailed()) - .andExpect(jsonPath("$.description.", containsString("expected-version"))); + .andExpect(jsonPath("$.description", containsString("expected-version"))); } @Test public void incorrectHeaderSent() throws Exception { mockWithExpectedVersion().perform(get(CATALOG_PATH) - .header(DEFAULT_API_VERSION_HEADER, "wrong-version") + .header(BrokerApiVersion.DEFAULT_API_VERSION_HEADER, "wrong-version") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isPreconditionFailed()) - .andExpect(jsonPath("$.description.", containsString("expected-version"))) - .andExpect(jsonPath("$.description.", containsString("wrong-version"))); + .andExpect(jsonPath("$.description", containsString("expected-version"))) + .andExpect(jsonPath("$.description", containsString("wrong-version"))); } @Test public void matchingHeaderSent() throws Exception { mockWithExpectedVersion().perform(get(CATALOG_PATH) - .header(DEFAULT_API_VERSION_HEADER, "expected-version") + .header(BrokerApiVersion.DEFAULT_API_VERSION_HEADER, "expected-version") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); } @@ -66,20 +65,20 @@ public class BrokerApiVersionInterceptorIntegrationTest { @Test public void anyHeaderSent() throws Exception { mockWithDefaultVersion().perform(get(CATALOG_PATH) - .header(DEFAULT_API_VERSION_HEADER, "ignored-version") + .header(BrokerApiVersion.DEFAULT_API_VERSION_HEADER, "ignored-version") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); } private MockMvc mockWithDefaultVersion() { return MockMvcBuilders.standaloneSetup(controller) - .addInterceptors(new BrokerApiVersionInterceptor(new BrokerApiVersion())) + .addInterceptors(new ApiVersionInterceptor(new BrokerApiVersion())) .setMessageConverters(new MappingJackson2HttpMessageConverter()).build(); } private MockMvc mockWithExpectedVersion() { return MockMvcBuilders.standaloneSetup(controller) - .addInterceptors(new BrokerApiVersionInterceptor(new BrokerApiVersion("expected-version"))) + .addInterceptors(new ApiVersionInterceptor(new BrokerApiVersion("expected-version"))) .setMessageConverters(new MappingJackson2HttpMessageConverter()).build(); } } diff --git a/src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorTest.java b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorTest.java similarity index 83% rename from src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorTest.java rename to spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorTest.java index 75a8d499..f9b9da8c 100644 --- a/src/test/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptorTest.java +++ b/spring-cloud-starter-service-broker-webmvc/src/test/java/org/springframework/cloud/servicebroker/webmvc/interceptor/ApiVersionInterceptorTest.java @@ -1,4 +1,4 @@ -package org.springframework.cloud.servicebroker.interceptor; +package org.springframework.cloud.servicebroker.webmvc.interceptor; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.atLeastOnce; @@ -12,20 +12,20 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.cloud.servicebroker.exception.ServiceBrokerApiVersionException; -import org.springframework.cloud.servicebroker.model.BrokerApiVersion; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.cloud.servicebroker.model.BrokerApiVersion; -public class BrokerApiVersionInterceptorTest { +public class ApiVersionInterceptorTest { @Mock private HttpServletRequest request; - - @Mock + + @Mock private HttpServletResponse response; - + @Mock private BrokerApiVersion brokerApiVersion; @@ -33,10 +33,10 @@ public class BrokerApiVersionInterceptorTest { public void setup() { MockitoAnnotations.initMocks(this); } - + @Test public void noBrokerApiVersionConfigured() throws IOException, ServletException, ServiceBrokerApiVersionException { - BrokerApiVersionInterceptor interceptor = new BrokerApiVersionInterceptor(null); + ApiVersionInterceptor interceptor = new ApiVersionInterceptor(null); assertTrue(interceptor.preHandle(request, response, null)); } @@ -47,8 +47,8 @@ public class BrokerApiVersionInterceptorTest { when(brokerApiVersion.getBrokerApiVersionHeader()).thenReturn(header); when(brokerApiVersion.getApiVersion()).thenReturn(version); when(request.getHeader(header)).thenReturn("version"); - - BrokerApiVersionInterceptor interceptor = new BrokerApiVersionInterceptor(brokerApiVersion); + + ApiVersionInterceptor interceptor = new ApiVersionInterceptor(brokerApiVersion); assertTrue(interceptor.preHandle(request, response, null)); verify(brokerApiVersion, atLeastOnce()).getApiVersion(); } @@ -61,7 +61,7 @@ public class BrokerApiVersionInterceptorTest { when(brokerApiVersion.getApiVersion()).thenReturn(version); when(request.getHeader(header)).thenReturn(version); - BrokerApiVersionInterceptor interceptor = new BrokerApiVersionInterceptor(brokerApiVersion); + ApiVersionInterceptor interceptor = new ApiVersionInterceptor(brokerApiVersion); assertTrue(interceptor.preHandle(request, response, null)); verify(brokerApiVersion, atLeastOnce()).getApiVersion(); } @@ -74,11 +74,11 @@ public class BrokerApiVersionInterceptorTest { when(brokerApiVersion.getBrokerApiVersionHeader()).thenReturn(header); when(brokerApiVersion.getApiVersion()).thenReturn(version); when(request.getHeader(header)).thenReturn(notVersion); - - BrokerApiVersionInterceptor interceptor = new BrokerApiVersionInterceptor(brokerApiVersion); + + ApiVersionInterceptor interceptor = new ApiVersionInterceptor(brokerApiVersion); interceptor.preHandle(request, response, null); verify(brokerApiVersion).getBrokerApiVersionHeader(); verify(brokerApiVersion).getApiVersion(); } - + } diff --git a/src/main/java/org/springframework/cloud/servicebroker/config/BrokerApiVersionConfig.java b/src/main/java/org/springframework/cloud/servicebroker/config/BrokerApiVersionConfig.java deleted file mode 100644 index 36f58c81..00000000 --- a/src/main/java/org/springframework/cloud/servicebroker/config/BrokerApiVersionConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.cloud.servicebroker.config; - -import org.springframework.cloud.servicebroker.interceptor.BrokerApiVersionInterceptor; -import org.springframework.cloud.servicebroker.model.BrokerApiVersion; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class BrokerApiVersionConfig { - @Bean - public BrokerApiVersionInterceptor brokerApiVersionInterceptor(BrokerApiVersion brokerApiVersion) { - return new BrokerApiVersionInterceptor(brokerApiVersion); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/servicebroker/config/ServiceBrokerAutoConfiguration.java b/src/main/java/org/springframework/cloud/servicebroker/config/ServiceBrokerAutoConfiguration.java deleted file mode 100644 index aa970071..00000000 --- a/src/main/java/org/springframework/cloud/servicebroker/config/ServiceBrokerAutoConfiguration.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.springframework.cloud.servicebroker.config; - -import org.springframework.cloud.servicebroker.model.BrokerApiVersion; -import org.springframework.cloud.servicebroker.model.Catalog; -import org.springframework.cloud.servicebroker.service.BeanCatalogService; -import org.springframework.cloud.servicebroker.service.CatalogService; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; -import org.springframework.cloud.servicebroker.service.NonBindableServiceInstanceBindingService; -import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ComponentScan(basePackages = {"org.springframework.cloud.servicebroker"}) -@ConditionalOnWebApplication -@AutoConfigureAfter(WebMvcAutoConfiguration.class) -public class ServiceBrokerAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(BrokerApiVersion.class) - public BrokerApiVersion brokerApiVersion() { - return new BrokerApiVersion(); - } - - @Bean - @ConditionalOnMissingBean(CatalogService.class) - public CatalogService beanCatalogService(Catalog catalog) { - return new BeanCatalogService(catalog); - } - - @Bean - @ConditionalOnMissingBean(ServiceInstanceBindingService.class) - public ServiceInstanceBindingService nonBindableServiceInstanceBindingService() { - return new NonBindableServiceInstanceBindingService(); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/servicebroker/config/WebMvcConfiguration.java b/src/main/java/org/springframework/cloud/servicebroker/config/WebMvcConfiguration.java deleted file mode 100644 index 4c21b327..00000000 --- a/src/main/java/org/springframework/cloud/servicebroker/config/WebMvcConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.springframework.cloud.servicebroker.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.servicebroker.interceptor.BrokerApiVersionInterceptor; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -@EnableWebMvc -public class WebMvcConfiguration extends WebMvcConfigurerAdapter { - private static final String V2_API_PATH_PATTERN = "/v2/**"; - - @Autowired - private BrokerApiVersionInterceptor brokerApiVersionInterceptor; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(brokerApiVersionInterceptor).addPathPatterns(V2_API_PATH_PATTERN); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptor.java b/src/main/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptor.java deleted file mode 100644 index 2a050855..00000000 --- a/src/main/java/org/springframework/cloud/servicebroker/interceptor/BrokerApiVersionInterceptor.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.springframework.cloud.servicebroker.interceptor; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.cloud.servicebroker.exception.ServiceBrokerApiVersionException; -import org.springframework.cloud.servicebroker.model.BrokerApiVersion; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -public class BrokerApiVersionInterceptor extends HandlerInterceptorAdapter { - - private final BrokerApiVersion version; - - public BrokerApiVersionInterceptor() { - this(null); - } - - public BrokerApiVersionInterceptor(BrokerApiVersion version) { - this.version = version; - } - - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, - Object handler) throws ServiceBrokerApiVersionException { - if (version != null && !anyVersionAllowed()) { - String apiVersion = request.getHeader(version.getBrokerApiVersionHeader()); - if (!version.getApiVersion().equals(apiVersion)) { - throw new ServiceBrokerApiVersionException(version.getApiVersion(), apiVersion); - } - } - return true; - } - - private boolean anyVersionAllowed() { - return BrokerApiVersion.API_VERSION_ANY.equals(version.getApiVersion()); - } - -} diff --git a/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java b/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java deleted file mode 100644 index 5ce873b6..00000000 --- a/src/main/java/org/springframework/cloud/servicebroker/model/BrokerApiVersion.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.springframework.cloud.servicebroker.model; - - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; - -@Getter -@ToString -@EqualsAndHashCode -public class BrokerApiVersion { - - public final static String DEFAULT_API_VERSION_HEADER = "X-Broker-Api-Version"; - public final static String API_VERSION_ANY = "*"; - public final static String API_VERSION_CURRENT = "2.13"; - - /** - * The name of the HTTP header field expected to contain the API version of the service broker client. - */ - private final String brokerApiVersionHeader; - - /** - * The version of the broker API supported by the broker. A value of null or - * API_VERSION_ANY will disable API version validation. - */ - private final String apiVersion; - - public BrokerApiVersion(String brokerApiVersionHeader, String apiVersion) { - this.brokerApiVersionHeader = brokerApiVersionHeader; - this.apiVersion = apiVersion; - } - - public BrokerApiVersion(String apiVersion) { - this(DEFAULT_API_VERSION_HEADER, apiVersion); - } - - public BrokerApiVersion() { - this(DEFAULT_API_VERSION_HEADER, API_VERSION_ANY); - } -} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 54f1ce35..00000000 --- a/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.servicebroker.config.ServiceBrokerAutoConfiguration \ No newline at end of file