5. 服务绑定

服务代理可以通过 服务绑定 向服务实例的消费者提供信息。服务绑定通常用于将服务实例资源的凭据暴露给应用程序。spring-doc.cadn.net.cn

如果服务目录中的任何计划的 bindable 字段设置为 true,服务代理必须提供 ServiceInstanceBindingService 接口的实现。
否则,平台不会调用服务代理的绑定方法,可使用该接口的默认实现。
每个方法接收一个包含平台请求所有详细信息的 Java 对象参数,并返回一个 Java 对象值,以向平台提供操作详情。spring-doc.cadn.net.cn

服务绑定的创建和删除操作可以同步或异步执行。spring-doc.cadn.net.cn

  • 当服务提供者在同步创建或删除服务绑定时,应阻塞相应的接口方法,并仅在操作成功完成或发生失败时向平台返回响应。spring-doc.cadn.net.cn

  • 在执行异步操作时,服务代理可以在操作完成前向平台返回响应,并在响应中表明该操作正在进行中。当指示为异步操作时,平台 轮询服务代理 以获取该操作的状态。spring-doc.cadn.net.cn

5.1. 服务绑定创建

服务代理必须提供 createServiceInstanceBinding() 方法的实现。spring-doc.cadn.net.cn

支持两种绑定类型:spring-doc.cadn.net.cn

此方法的响应可返回两种 Java 对象类型之一,以反映两种支持的绑定类型。spring-doc.cadn.net.cn

服务 broker 可以为所有绑定请求生成一组凭据,或者为每个绑定请求提供唯一的凭据。spring-doc.cadn.net.cn

5.1.1。事件注册表

您可以使用事件进一步自定义服务绑定创建。 要实现此目的: </body>\ </html>" }spring-doc.cadn.net.cn

  1. Autowire the CreateServiceInstanceBindingEventFlowRegistry bean.spring-doc.cadn.net.cn

  2. 使用其中一个的 addInitializationFlow()addCompletionFlow()addErrorFlow() 方法,在创建服务绑定的各个阶段运行自定义响应式流。spring-doc.cadn.net.cn

5.2. 服务绑定删除操作

服务代理必须提供 deleteServiceInstanceBinding() 方法的实现。spring-doc.cadn.net.cn

在创建操作中提供的凭据应在删除操作中取消预配置。spring-doc.cadn.net.cn

5.2.1. 事件注册表

你可以在进一步自定义服务绑定删除时使用事件。
为此:
. 将 1 Bean 自动连线。spring-doc.cadn.net.cn

  1. 使用 addInitializationFlow()addCompletionFlow()addErrorFlow() 方法中的任何一个来在删除服务绑定的各个阶段运行自定义反应流。spring-doc.cadn.net.cn

服务绑定操作状态检索

如果任何创建或删除操作可以向平台返回“操作正在进行”的异步响应,则服务broker必须实现getLastOperation()方法。否则,此方法永远不会被平台调用,可以使用接口中的默认实现。spring-doc.cadn.net.cn

平台轮询此方法服务 broker,获取具有异步操作的 service 实例,直到 service broker 表示操作已完成成功或发生故障。spring-doc.cadn.net.cn

5.3.1. 事件注册表

你可以使用事件来进一步自定义服务绑定最后操作请求。 为此: . 自动装配 AsyncOperationServiceInstanceBindingEventFlowRegistry 组件。spring-doc.cadn.net.cn

  1. 使用下面提供的 addInitializationFlow()addCompletionFlow()addErrorFlow() 中的任意一种方法来注册在各个阶段的操作检索过程中要运行的自定义响应式流。spring-doc.cadn.net.cn

5.4 服务绑定检索

如果服务目录中的bindings_retrievable字段设置为true,则服务目录必须提供getServiceInstanceBinding()方法的实现。否则,此方法永远不会被平台调用,可以使用接口中的默认实现。spring-doc.cadn.net.cn

服务代理负责维护任何支持检索操作所需的必要服务绑定状态。spring-doc.cadn.net.cn

5.5. 示例实现

以下示例实现了服务绑定:spring-doc.cadn.net.cn

package com.example.servicebroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.GetServiceInstanceAppBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.GetServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.GetServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService;
import org.springframework.stereotype.Service;

@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. 示例事件流配置

有多种配置服务绑定事件流的方法。一个选项是自动装配一个或多个注册表并直接与注册表交互。另一个选项是为特定流定义bean。这些bean会被自动识别并添加到适当的注册表中。最后一种选项是声明一个新的注册表bean。然而,要注意的是,定义一个新的注册表bean会覆盖提供的自动配置。spring-doc.cadn.net.cn

5.6.1。选项 1:自动装配注册表

本示例配置服务绑定事件流:spring-doc.cadn.net.cn

package com.example.servicebroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.GetLastServiceBindingOperationRequest;
import org.springframework.cloud.servicebroker.model.binding.GetLastServiceBindingOperationResponse;
import org.springframework.cloud.servicebroker.service.events.AsyncOperationServiceInstanceBindingEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.CreateServiceInstanceBindingEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.DeleteServiceInstanceBindingEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingInitializationFlow;
import org.springframework.context.annotation.Configuration;

@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 选项2:事件流Bean

可选地,您可以为各个流配置 bean,如下所示:spring-doc.cadn.net.cn

package com.example.servicebroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest;
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse;
import org.springframework.cloud.servicebroker.model.binding.GetLastServiceBindingOperationRequest;
import org.springframework.cloud.servicebroker.model.binding.GetLastServiceBindingOperationResponse;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceBindingInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceBindingInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceBindingInitializationFlow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@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();
			}
		};
	}
}