5. 服务绑定
默认情况下,Spring Cloud App Broker 不包含管理其服务实例绑定的功能。App Broker 提供了服务代理作者可以实现的接口,以控制服务绑定。
5.1. 创建服务绑定
服务代理应用程序可以实现CreateServiceInstanceAppBindingWorkflow接口。或者,服务代理应用程序可以实现由 Spring Cloud Open Service Broker 提供的ServiceInstanceBindingService接口。请参阅服务绑定,位于Spring Cloud Open Service Broker 文档中。
5.2. 删除服务绑定
服务代理应用程序可以实现DeleteServiceInstanceBindingWorkflow接口。或者,服务代理应用程序可以实现由 Spring Cloud Open Service Broker 提供的ServiceInstanceBindingService接口。请参阅服务绑定,位于Spring Cloud Open Service Broker 文档中。
5.3. 持久化服务实例绑定状态
Spring Cloud App Broker 提供了 ServiceInstanceBindingStateRepository 接口,用于持久化服务实例绑定状态。默认实现是 InMemoryServiceInstanceBindingStateRepository,它使用内存中的 Map 来保存状态,并提供了简单的入门体验。为了使用适当的数据库来持久化状态,请在您的应用程序中实现 ServiceInstanceBindingStateRepository。
The InMemoryServiceInstanceBindingStateRepository 仅出于演示和测试目的提供。它不适合用于生产应用程序! |
5.3.1. 示例实现
以下示例显示了服务实例绑定状态存储库的实现:
package com.example.appbroker;
class ExampleServiceInstanceBindingStateRepository implements ServiceInstanceBindingStateRepository {
private final ServiceInstanceBindingStateCrudRepository serviceInstanceBindingStateCrudRepository;
ExampleServiceInstanceBindingStateRepository(
ServiceInstanceBindingStateCrudRepository serviceInstanceBindingStateCrudRepository) {
this.serviceInstanceBindingStateCrudRepository = serviceInstanceBindingStateCrudRepository;
}
@Override
public Mono<ServiceInstanceState> saveState(String serviceInstanceId, String bindingId, OperationState state,
String description) {
return serviceInstanceBindingStateCrudRepository
.findByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId)
.switchIfEmpty(Mono.just(new ServiceInstanceBinding()))
.flatMap(binding -> {
binding.setServiceInstanceId(serviceInstanceId);
binding.setBindingId(bindingId);
binding.setOperationState(state);
binding.setDescription(description);
return Mono.just(binding);
})
.flatMap(serviceInstanceBindingStateCrudRepository::save)
.map(ExampleServiceInstanceBindingStateRepository::toServiceInstanceState);
}
@Override
public Mono<ServiceInstanceState> getState(String serviceInstanceId, String bindingId) {
return serviceInstanceBindingStateCrudRepository
.findByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId)
.switchIfEmpty(Mono.error(new IllegalArgumentException(
"Unknown binding: serviceInstanceId=" + serviceInstanceId + ", bindingId=" + bindingId)))
.map(ExampleServiceInstanceBindingStateRepository::toServiceInstanceState);
}
@Override
public Mono<ServiceInstanceState> removeState(String serviceInstanceId, String bindingId) {
return getState(serviceInstanceId, bindingId)
.doOnNext(serviceInstanceState -> serviceInstanceBindingStateCrudRepository
.deleteByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId));
}
private static ServiceInstanceState toServiceInstanceState(ServiceInstanceBinding binding) {
return new ServiceInstanceState(binding.getOperationState(), binding.getDescription(), null);
}
}
持久化服务实例绑定状态的一种选择是使用 Spring Data CrudRepository。以下示例展示了一个 ReactiveCrudRepository 实现:
package com.example.appbroker;
interface ServiceInstanceBindingStateCrudRepository extends ReactiveCrudRepository<ServiceInstanceBinding, Long> {
@Query("select * from service_instance_binding " +
"where service_instance_id = :service_instance_id " +
"and binding_id = :binding_id")
Mono<ServiceInstanceBinding> findByServiceInstanceIdAndBindingId(
@Param("service_instance_id") String serviceInstanceId,
@Param("binding_id") String bindingId);
@Query("delete from service_instance_binding " +
"where service_instance_id = :service_instance_id " +
"and binding_id = :binding_id")
Mono<Void> deleteByServiceInstanceIdAndBindingId(
@Param("service_instance_id") String serviceInstanceId,
@Param("binding_id") String bindingId);
}
一个模型对象对于使用 CrudRepository 持久化数据是必要的。以下示例展示了一个 ServiceInstanceBinding 模型:
package com.example.appbroker;
class ServiceInstanceBinding {
@Id
private Long id;
private String bindingId;
private String serviceInstanceId;
private String description;
private OperationState operationState;
public ServiceInstanceBinding() {
}
public ServiceInstanceBinding(String bindingId, String serviceInstanceId, String description,
OperationState operationState) {
this.bindingId = bindingId;
this.serviceInstanceId = serviceInstanceId;
this.description = description;
this.operationState = operationState;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBindingId() {
return bindingId;
}
public void setBindingId(String bindingId) {
this.bindingId = bindingId;
}
public String getServiceInstanceId() {
return serviceInstanceId;
}
public void setServiceInstanceId(String serviceInstanceId) {
this.serviceInstanceId = serviceInstanceId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public OperationState getOperationState() {
return operationState;
}
public void setOperationState(OperationState operationState) {
this.operationState = operationState;
}
}