5. 服务绑定
Service Broker 可以通过服务绑定向服务实例的使用者提供信息。 服务绑定通常用于向应用程序公开服务实例资源的凭据。
如果bindable
field 设置为true
对于 Service Catalog 中的任何计划,Service Broker 必须提供ServiceInstanceBindingService
接口。
否则,平台不会调用 Service Broker 的绑定方法,并且可以使用此接口的默认实现。
每个方法都接收一个 Java 对象参数,该参数包含来自平台的请求的所有详细信息,并返回一个 Java 对象值,该值向平台提供作的详细信息。
服务绑定的 create 和 delete作可以同步或异步执行。
-
当 Service Broker 同步创建或删除服务绑定时,相应的接口方法应仅在作成功完成或发生故障时阻止并返回对平台的响应。
-
异步执行作时,Service Broker 可以在作完成之前向平台返回响应,并在响应中指示作正在进行中。 当指示异步作时,平台会轮询 Service Broker 以获取作的状态。
5.1. 服务绑定创建
Service Broker 必须提供createServiceInstanceBinding()
方法。
支持两种类型的绑定:
-
应用程序绑定可用于向应用程序提供凭据、日志耗尽和卷服务。
-
路由绑定可用于为平台提供路由,以便在代理请求时使用。
此方法的响应允许返回两种 Java 对象类型之一,以反映支持的两种类型的绑定。
Service Broker 可以为所有绑定请求生成一组凭据,也可以为每个绑定请求提供唯一凭据。
5.1.1. 事件注册中心
您可以使用事件进一步自定义服务绑定创建。 为此,请执行以下作:
-
使用
addInitializationFlow()
,addCompletionFlow()
或addErrorFlow()
方法注册自定义反应流,以便在创建服务绑定的各个阶段运行。
5.2. 服务绑定删除
Service Broker 必须提供deleteServiceInstanceBinding()
方法。
在 create作中预置的任何凭证都应由 delete作取消预置。
5.2.1. 事件注册表
您可以使用事件进一步自定义服务绑定删除。
为此,请执行以下作:
.自动装配DeleteServiceInstanceBindingEventFlowRegistry
豆。
-
使用
addInitializationFlow()
,addCompletionFlow()
或addErrorFlow()
注册自定义反应流的方法,以便在删除服务绑定的各个阶段运行。
5.3. 服务绑定作状态检索
如果任何创建或删除作可以向平台返回异步“operation in progress”响应,则 Service Broker 必须提供getLastOperation()
方法。否则,平台永远不会调用此方法,并且可以使用接口中的默认实现。
平台会轮询 Service Broker 的此方法,以查找正在进行异步作的服务实例,直到 Service Broker 指示作已成功完成或发生故障。
5.3.1. 事件注册中心
您可以使用事件进一步自定义服务绑定上次作请求。
为此,请执行以下作:
.自动装配AsyncOperationServiceInstanceBindingEventFlowRegistry
豆。
-
使用
addInitializationFlow()
,addCompletionFlow()
或addErrorFlow()
方法注册自定义反应流,以便在上次作检索的各个阶段运行。
5.4. 服务绑定检索
如果bindings_retrievable
field 设置为true
在服务目录中,服务目录必须提供getServiceInstanceBinding()
方法。
否则,平台永远不会调用此方法,并且可以使用接口中的默认实现。
Service Broker 负责维护支持检索作所需的任何服务绑定状态。
5.5. 示例实现
以下示例实现服务绑定:
package com.example.servicebroker;
@Service
public class ExampleServiceBindingService implements ServiceInstanceBindingService {
@Override
public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(CreateServiceInstanceBindingRequest request) {
String serviceInstanceId = request.getServiceInstanceId();
String bindingId = request.getBindingId();
//
// create credentials and store for later retrieval
//
String url = new String(/* build a URL to access the service instance */);
String bindingUsername = new String(/* create a user */);
String bindingPassword = new String(/* create a password */);
CreateServiceInstanceBindingResponse response = CreateServiceInstanceAppBindingResponse.builder()
.credentials("url", url)
.credentials("username", bindingUsername)
.credentials("password", bindingPassword)
.bindingExisted(false)
.async(true)
.build();
return Mono.just(response);
}
@Override
public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(DeleteServiceInstanceBindingRequest request) {
String serviceInstanceId = request.getServiceInstanceId();
String bindingId = request.getBindingId();
//
// delete any binding-specific credentials
//
return Mono.just(DeleteServiceInstanceBindingResponse.builder()
.async(true)
.build());
}
@Override
public Mono<GetServiceInstanceBindingResponse> getServiceInstanceBinding(GetServiceInstanceBindingRequest request) {
String serviceInstanceId = request.getServiceInstanceId();
String bindingId = request.getBindingId();
//
// retrieve the details of the specified service binding
//
String url = new String(/* retrieved URL */);
String bindingUsername = new String(/* retrieved user */);
String bindingPassword = new String(/* retrieved password */);
GetServiceInstanceBindingResponse response = GetServiceInstanceAppBindingResponse.builder()
.credentials("username", bindingUsername)
.credentials("password", bindingPassword)
.credentials("url", url)
.build();
return Mono.just(response);
}
}
5.6. Example Event Flow Configuration
There are multiple ways to configure service binding event flows.
One option is to autowire one or more registries and interact with the registry directly.
Another option is to define beans for specific flows.
These beans are automatically identified and added to the appropriate registry.
A final option is to declare a new registry bean.
However, be aware that defining a new registry bean overrides the provided auto-configuration.
5.6.1. Option 1: Autowire Registries
The following example configures service binding event flows:
package com.example.servicebroker;
@Configuration
public class ExampleServiceBindingEventFlowsConfiguration {
private final CreateServiceInstanceBindingEventFlowRegistry createRegistry;
private final DeleteServiceInstanceBindingEventFlowRegistry deleteRegistry;
private final AsyncOperationServiceInstanceBindingEventFlowRegistry asyncRegistry;
public ExampleServiceBindingEventFlowsConfiguration(
CreateServiceInstanceBindingEventFlowRegistry createRegistry,
DeleteServiceInstanceBindingEventFlowRegistry deleteRegistry,
AsyncOperationServiceInstanceBindingEventFlowRegistry asyncRegistry) {
this.createRegistry = createRegistry;
this.deleteRegistry = deleteRegistry;
this.asyncRegistry = asyncRegistry;
prepareCreateEventFlows()
.then(prepareDeleteEventFlows())
.then(prepareLastOperationEventFlows())
.subscribe();
}
private Mono<Void> prepareCreateEventFlows() {
return Mono.just(createRegistry)
.map(registry -> registry.addInitializationFlow(new CreateServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(CreateServiceInstanceBindingRequest request) {
//
// do something before the instance is created
//
return Mono.empty();
}
})
.then(registry.addCompletionFlow(new CreateServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(CreateServiceInstanceBindingRequest request,
CreateServiceInstanceBindingResponse response) {
//
// do something after the instance is created
//
return Mono.empty();
}
}))
.then(registry.addErrorFlow(new CreateServiceInstanceBindingErrorFlow() {
@Override
public Mono<Void> error(CreateServiceInstanceBindingRequest request, Throwable t) {
//
// do something if an error occurs while creating an instance
//
return Mono.empty();
}
})))
.then();
}
private Mono<Void> prepareDeleteEventFlows() {
return Mono.just(deleteRegistry)
.map(registry -> registry.addInitializationFlow(new DeleteServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(DeleteServiceInstanceBindingRequest request) {
//
// do something before the instance is deleted
//
return Mono.empty();
}
})
.then(registry.addCompletionFlow(new DeleteServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(DeleteServiceInstanceBindingRequest request,
DeleteServiceInstanceBindingResponse response) {
//
// do something after the instance is deleted
//
return Mono.empty();
}
}))
.then(registry.addErrorFlow(new DeleteServiceInstanceBindingErrorFlow() {
@Override
public Mono<Void> error(DeleteServiceInstanceBindingRequest request, Throwable t) {
//
// do something if an error occurs while deleting an instance
//
return Mono.empty();
}
})))
.then();
}
private Mono<Void> prepareLastOperationEventFlows() {
return Mono.just(asyncRegistry)
.map(registry -> registry.addInitializationFlow(new AsyncOperationServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(GetLastServiceBindingOperationRequest request) {
//
// do something before the instance is deleted
//
return Mono.empty();
}
})
.then(registry.addCompletionFlow(new AsyncOperationServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(GetLastServiceBindingOperationRequest request,
GetLastServiceBindingOperationResponse response) {
//
// do something after the instance is deleted
//
return Mono.empty();
}
}))
.then(registry.addErrorFlow(new AsyncOperationServiceInstanceBindingErrorFlow() {
public Mono<Void> error(GetLastServiceBindingOperationRequest request, Throwable t) {
//
// do something if an error occurs while deleting an instance
//
return Mono.empty();
}
})))
.then();
}
}
5.6.2. Option 2: Event Flow Beans
Optionally, you can configure beans for the individual flows, as follows:
package com.example.servicebroker;
@Configuration
public class ExampleServiceBindingEventFlowsConfiguration2 {
//
// Create Service Instance Binding flows
//
@Bean
public CreateServiceInstanceBindingInitializationFlow createServiceInstanceBindingInitializationFlow() {
return new CreateServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(CreateServiceInstanceBindingRequest request) {
//
// do something before the service instance binding completes
//
return Mono.empty();
}
};
}
@Bean
public CreateServiceInstanceBindingCompletionFlow createServiceInstanceBindingCompletionFlow() {
return new CreateServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(CreateServiceInstanceBindingRequest request,
CreateServiceInstanceBindingResponse response) {
//
// do something after the service instance binding completes
//
return Mono.empty();
}
};
}
@Bean
public CreateServiceInstanceBindingErrorFlow createServiceInstanceBindingErrorFlow() {
return new CreateServiceInstanceBindingErrorFlow() {
@Override
public Mono<Void> error(CreateServiceInstanceBindingRequest request, Throwable t) {
//
// do something if an error occurs while creating a service instance binding
//
return Mono.empty();
}
};
}
//
// Delete Service Instance Binding flows
//
@Bean
public DeleteServiceInstanceBindingInitializationFlow deleteServiceInstanceBindingInitializationFlow() {
return new DeleteServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(DeleteServiceInstanceBindingRequest request) {
//
// do something before the service instance binding is deleted
//
return Mono.empty();
}
};
}
@Bean
public DeleteServiceInstanceBindingCompletionFlow deleteServiceInstanceBindingCompletionFlow() {
return new DeleteServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(DeleteServiceInstanceBindingRequest request,
DeleteServiceInstanceBindingResponse response) {
//
// do something after the service instance binding is deleted
//
return Mono.empty();
}
};
}
@Bean
public DeleteServiceInstanceBindingErrorFlow deleteServiceInstanceBindingErrorFlow() {
return new DeleteServiceInstanceBindingErrorFlow() {
@Override
public Mono<Void> error(DeleteServiceInstanceBindingRequest request, Throwable t) {
//
// do something if an error occurs while deleting a service instance binding
//
return Mono.empty();
}
};
}
//
// Get Last Service Instance Binding Operation flows
//
@Bean
public AsyncOperationServiceInstanceBindingInitializationFlow getLastOperationServiceInstanceBindingInitializationFlow() {
return new AsyncOperationServiceInstanceBindingInitializationFlow() {
@Override
public Mono<Void> initialize(GetLastServiceBindingOperationRequest request) {
//
// do something before getting the last operation
//
return Mono.empty();
}
};
}
@Bean
public AsyncOperationServiceInstanceBindingCompletionFlow getLastOperationServiceInstanceBindingCompletionFlow() {
return new AsyncOperationServiceInstanceBindingCompletionFlow() {
@Override
public Mono<Void> complete(GetLastServiceBindingOperationRequest request,
GetLastServiceBindingOperationResponse response) {
//
// do something after getting the last operation
//
return Mono.empty();
}
};
}
@Bean
public AsyncOperationServiceInstanceBindingErrorFlow getLastOperationServiceInstanceBindingErrorFlow() {
return new AsyncOperationServiceInstanceBindingErrorFlow() {
@Override
public Mono<Void> error(GetLastServiceBindingOperationRequest request, Throwable t) {
//
// do something if an error occurs while getting the last operation
//
return Mono.empty();
}
};
}
}