Implement Service Broker with Spring Boot #cf_tokyo
-
Upload
toshiaki-maki -
Category
Technology
-
view
1.004 -
download
4
Transcript of Implement Service Broker with Spring Boot #cf_tokyo
Implement Service Broker with Spring Boot
Toshiaki Maki (@making)Sr. Solutions Architect @Pivotal2016-‐‑‒06-‐‑‒01 Cloud Foundry Tokyo Meetup #2
Who am I ?•Toshiaki Maki (@making)•https://blog.ik.am•Sr. Solutions Architect•Spring Framework enthusiast
SpringFramework徹底⼊入⾨門(Coming Soon?)
パーフェクトJava EE(Coming Soon?)
Today's Topic•Service Broker Overview•Spring Boot Overview•Implement Service Broker
with Spring Boot
Services in Cloud FoundryApplication
Service Broker
Service Instance
User Provided Service
Managed ServicesMySQL
RedisRabbitMQ ex.) Oracle DB
create-‐‑‒user-‐‑‒provided-‐‑‒servicecreate-‐‑‒service
bind-‐‑‒service
marketplace
Services in Cloud FoundryApplication
Service Broker
Service Instance
User Provided Service
Managed ServicesMySQL
RedisRabbitMQ ex.) Oracle DB
create-‐‑‒user-‐‑‒provided-‐‑‒servicecreate-‐‑‒service
bind-‐‑‒service
marketplace
👇
7 APIs in Service Broker• GET /v2/catalog• PUT /v2/service_̲instances/:instance_̲id• PATCH /v2/service_̲instances/:instance_̲id• DELETE /v2/service_̲instances/:instance_̲id• PUT /v2/service_̲instances/:instance_̲id/service_̲bindings/:binding_̲id• DELETE /v2/service_̲instances/:instance_̲id/service_̲bindings/:binding_̲id• GET /v2/service_̲instances/:instance_̲id/last_̲operation
API Overview (create service)
Cloud Controller
Service
cf create-service PUT/v2/service_̲instances/:instance_̲id
Service Broker
cf delete-service DELETE/v2/service_̲instances/:instance_̲id
API Overview (bind service)
Cloud Controller
Service
cf bind-service PUT/v2/service_̲instances/:instance_̲id
/service_̲bindings/:binding_̲id
Service Broker
cf unbind-service DELETE/v2/service_̲instances/:instance_̲id
/service_̲bindings/:binding_̲id
@SpringBootApplication@RestControllerpublic class DemoApplication {
public static void main(String[] args) {SpringBootApplication.run(
DemoApplication.class, args);}@GetMapping("/")String hello() {
return "Hello World";}
}
@SpringBootApplication@RestControllerpublic class DemoApplication {
public static void main(String[] args) {SpringBootApplication.run(
DemoApplication.class, args);}@GetMapping("/")String hello() {
return "Hello World";}
}
@SpringBootApplication@RestControllerpublic class DemoApplication {
public static void main(String[] args) {SpringBootApplication.run(
DemoApplication.class, args);}@GetMapping("/")String hello() {
return "Hello World!";}
}
API Overview
Cloud Controller
Service
cf create-service PUT/v2/service_̲instances/:instance_̲id
Service Broker
cf delete-service DELETE/v2/service_̲instances/:instance_̲id
Implement APIs
@SpringBootApplication @RestControllerpublic class FakeServiceBroker {
// ...@GetMapping("/v2/catalog")CatalogResponse showCatalog() {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}")CreateResponse createServiceInstance(
@PathVariable String instanceId, @RequestBody CreateRequest req) {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}/service_bindings/{bindingId}")BindResponse createServiceBinding(
@PathVariable String instanceId ,@PathVariable String bindingId , @RequestBody BindRequest req) {/*...*/}
// ...}
@SpringBootApplication @RestControllerpublic class FakeServiceBroker {
// ...@GetMapping("/v2/catalog")CatalogResponse showCatalog() {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}")CreateResponse createServiceInstance(
@PathVariable String instanceId, @RequestBody CreateRequest req) {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}/service_bindings/{bindingId}")BindResponse createServiceBinding(
@PathVariable String instanceId ,@PathVariable String bindingId , @RequestBody BindRequest req) {/*...*/}
// ...}
A lot ofparameters
Need to handle Exceptions ...
@SpringBootApplication @RestControllerpublic class FakeServiceBroker {
// ...@GetMapping("/v2/catalog")Map<String, Object> showCatalog() {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}")Map<String, Object> createServiceInstance(
@PathVariable String instanceId, @RequestBody Map<String, Object> req) {/*...*/}
@PutMapping("/v2/service_instances/{instanceId}/service_bindings/{bindingId}")Map<String, Object> createServiceBinding(
@PathVariable String instanceId ,@PathVariable String bindingId , @RequestBody Map<String, Object> req) {/*...*/}
// ...}
There is a convenient way
😎
Spring Cloud CloudFoundry Service Broker
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-cloudfoundry-
service-broker</artifactId><version>1.0.0.RC3</version>
</dependency>https://github.com/spring-‐cloud/spring-‐cloud-‐cloudfoundry-‐service-‐broker
Service Broker API Version: 2.8 (cf-‐‑‒release v226+)
ServiceInstanceController
ServiceInstanceService
@PutMappingcreateServiceInstance
createServiceInstance
ServiceInstanceController
ServiceInstanceService
@PutMappingcreateServiceInstance
createServiceInstance
Provided You implement
@Componentpublic class FakeServiceInstanceService
implements ServiceInstanceService {public CreateServiceInstanceResponse createServiceInstance(
CreateServiceInstanceRequest req) {String serviceInstanceId = req.getServiceInstanceId();// ...return new CreateServiceInstanceResponse();
}
public GetLastServiceOperationResponse getLastOperation(GetLastServiceOperationRequest req) {/* ... */}
public DeleteServiceInstanceResponse deleteServiceInstance(DeleteServiceInstanceRequest req) {/* ... */}
public UpdateServiceInstanceResponse updateServiceInstance(UpdateServiceInstanceRequest req) {/* ... */}}
@Componentpublic class FakeServiceInstanceService
implements ServiceInstanceService {public CreateServiceInstanceResponse createServiceInstance(
CreateServiceInstanceRequest req) {String serviceInstanceId = req.getServiceInstanceId();// ...return new CreateServiceInstanceResponse();
}
public GetLastServiceOperationResponse getLastOperation(GetLastServiceOperationRequest req) {/* ... */}
public DeleteServiceInstanceResponse deleteServiceInstance(DeleteServiceInstanceRequest req) {/* ... */}
public UpdateServiceInstanceResponse updateServiceInstance(UpdateServiceInstanceRequest req) {/* ... */}}
Corresponds toPUT /v2/service_̲instances/:instance_̲id
@Componentpublic class FakeServiceInstanceBindingService
implements ServiceInstanceBindingService {public CreateServiceInstanceBindingResponse createServiceInstanceBinding(
CreateServiceInstanceBindingRequest req) {String serviceInstanceId = req.getServiceInstanceId();String bindingId = req.getBindingId();// ...Map<String, Object> credentials = new HashMap<String, Object>() {{put("url", "...");put("username", "...");put("password", "...");
}};return new CreateServiceInstanceAppBindingResponse()
.withCredentials(credentials);}public void deleteServiceInstanceBinding(
DeleteServiceInstanceBindingRequest req) {// ...
}}
@Componentpublic class FakeServiceInstanceBindingService
implements ServiceInstanceBindingService {public CreateServiceInstanceBindingResponse createServiceInstanceBinding(
CreateServiceInstanceBindingRequest req) {String serviceInstanceId = req.getServiceInstanceId();String bindingId = req.getBindingId();// ...Map<String, Object> credentials = new HashMap<String, Object>() {{put("url", "...");put("username", "...");put("password", "...");
}};return new CreateServiceInstanceAppBindingResponse()
.withCredentials(credentials);}public void deleteServiceInstanceBinding(
DeleteServiceInstanceBindingRequest req) {// ...
}}
Corresponds toPUT /v2/service_̲instances/:instance_̲id
/service_̲bindings/:binding_̲id
@SpringBootApplicationpublic class FakeServiceBroker {
public static void main(String[] args) {SpringBootApplication.run(
FakeServiceBroker.class, args);}@BeanCatalog catalog() {
return new Catalog(singletonList(new ServiceDefinition(
"fake-broker","p-fake","A fake service broker", ...)));
}}
@SpringBootApplicationpublic class FakeServiceBroker {
public static void main(String[] args) {SpringBootApplication.run(
FakeServiceBroker.class, args);}@BeanCatalog catalog() {
return new Catalog(singletonList(new ServiceDefinition(
"fake-broker","p-fake","A fake service broker", ...)));
}}
Corresponds to GET /v2/catalog
Authentication Configuration
security.user.name=fakesecurity.user.password=fake
application.properties
Deploy Service Brokerto Cloud Foundry
$ ./mvnw clean package$ cf push fake -p target/fake-1.0.0-SNAPSHOT.jar$ curl http://fake.local.pcfdev.io/v2/catalog
Enable Service Broker
$ cf create-service-broker p-fake fake fake ¥http://fake.local.pcfdev.io
$ cf enable-service-access p-fake
Service Name Username Password
Enable Service Broker
$ cf create-service-broker p-fake fake fake ¥http://fake.cfapp.io
Server error, status code: 403, error code: 10003, message: You are not authorized to
perform the requested action😫
$ cf create-service-broker p-fake fake fake ¥http://fake.cfapps.io ¥--space-scoped
Enable Service Broker(Space Scoped)
CF CLI 6.16.0+
References• https://github.com/spring-‐‑‒cloud/spring-‐‑‒cloud-‐‑‒cloudfoundry-‐‑‒service-‐‑‒broker• https://github.com/spring-‐‑‒cloud-‐‑‒samples/cloudfoundry-‐‑‒service-‐‑‒broker
• https://github.com/making/fake-‐‑‒service-‐‑‒broker• https://github.com/making/caffeine-‐‑‒broker
• https://github.com/pivotal-‐‑‒cf/brokerapi (similar project in Golang)