5. 服务绑定

默认情况下,Spring Cloud App Broker 不包含用于管理与其服务实例的绑定的功能。App Broker 提供了 Service Broker 作者可以实施的接口来控制服务绑定。spring-doc.cn

5.1. 创建服务绑定

Service Broker 应用程序可以实现 CreateServiceInstanceAppBindingWorkflow 接口。或者,Service Broker 应用程序可以实现 Spring Cloud Open Service Broker 提供的接口。请参阅 Spring Cloud Open Service Broker 文档中的服务绑定ServiceInstanceBindingServicespring-doc.cn

5.2. 删除服务绑定

Service Broker 应用程序可以实现 DeleteServiceInstanceBindingWorkflow 接口。或者,Service Broker 应用程序可以实现 Spring Cloud Open Service Broker 提供的接口。请参阅 Spring Cloud Open Service Broker 文档中的服务绑定ServiceInstanceBindingServicespring-doc.cn

5.3. 持久化服务实例绑定状态

Spring Cloud App Broker 提供了 ServiceInstanceBindingStateRepository 接口,用于持久化服务实例绑定状态。默认实现是 InMemoryServiceInstanceBindingStateRepository,它使用内存中来保存状态,并提供简单的入门体验。为了使用适当的数据库来持久保存状态,请在您的应用程序中实现。MapServiceInstanceBindingStateRepositoryspring-doc.cn

仅用于演示和测试目的。它不适合生产应用!InMemoryServiceInstanceBindingStateRepository

5.3.1. 示例实现

以下示例显示了服务实例绑定状态存储库实现:spring-doc.cn

package com.example.appbroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.appbroker.state.ServiceInstanceBindingStateRepository;
import org.springframework.cloud.appbroker.state.ServiceInstanceState;
import org.springframework.cloud.servicebroker.model.instance.OperationState;

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 。以下示例显示了一个实现:CrudRepositoryReactiveCrudRepositoryspring-doc.cn

package com.example.appbroker;

import reactor.core.publisher.Mono;

import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;

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);

}

模型对象对于使用 .以下示例显示了一个模型:CrudRepositoryServiceInstanceBindingspring-doc.cn

package com.example.appbroker;

import org.springframework.cloud.servicebroker.model.instance.OperationState;
import org.springframework.data.annotation.Id;

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;
	}

}