4. 服务实例

Service Broker 负责预置其目录中公布的服务,并在底层云平台中管理其生命周期。 代理创建的服务称为服务实例。spring-doc.cn

Service Broker 必须实现 ServiceInstanceService 接口,并提供该接口所需方法的实现。 每个方法都接收一个 Java 对象参数,该参数包含来自平台的请求的所有详细信息,并返回一个 Java 对象值,该值向平台提供操作的详细信息。spring-doc.cn

服务实例的创建、更新和删除操作可以同步或异步执行。spring-doc.cn

  • 当 Service Broker 同步创建、更新或删除服务实例时,相应的接口方法应仅在操作成功完成或发生故障时阻止并返回对平台的响应。spring-doc.cn

  • 异步执行操作时,Service Broker 可以在操作完成之前向平台返回响应,并在响应中指示操作正在进行中。 当指示异步操作时,平台会轮询 Service Broker 以获取操作的状态。spring-doc.cn

4.1. 服务实例创建

Service Broker 必须提供 createServiceInstance() 方法的实现。spring-doc.cn

Service Broker 通常在创建服务实例时在平台或其他系统中预置资源。 Service Broker 负责跟踪与服务实例关联的任何资源,以便将来检索、更新或删除。spring-doc.cn

4.1.1. 事件注册表

可以通过利用事件进一步自定义服务实例的创建。 为此,请执行以下操作:spring-doc.cn

  1. 自动装配 CreateServiceInstanceEventFlowRegistry Bean。spring-doc.cn

  2. 使用 addInitializationFlow()、addCompletionFlow() addErrorFlow() 方法之一注册自定义反应流,以便在创建服务实例的各个阶段运行。spring-doc.cn

4.2. 服务实例更新

如果该字段在服务目录中设置为 ,则 Service Broker 必须提供 updateServiceInstance() 方法的实现。 否则,平台永远不会调用此方法,并且可以使用接口中的默认实现。plan_updateabletruespring-doc.cn

服务代理可以在更新服务实例或部署新资源时修改现有资源的配置。spring-doc.cn

4.2.1. 事件注册表

可以通过利用事件进一步自定义服务实例更新。 为此,请执行以下操作:spring-doc.cn

  1. 自动装配UpdateServiceInstanceEventFlowRegistry Bean。spring-doc.cn

  2. 使用 addInitializationFlow()、addCompletionFlow()addErrorFlow() 方法之一注册自定义反应流,以便在更新服务实例的各个阶段运行。spring-doc.cn

4.3. 服务实例删除

deleteServiceInstance() 方法的实现必须由 Service Broker 提供。spring-doc.cn

在 create 操作中预置的任何资源都应由 delete 操作取消预置。spring-doc.cn

4.3.1. 事件注册中心

可以通过使用事件进一步自定义服务实例删除。 为此,请执行以下操作:spring-doc.cn

  1. 自动装配DeleteServiceInstanceEventFlowRegistry Bean。spring-doc.cn

  2. 使用 addInitializationFlow()、addCompletionFlow()addErrorFlow() 方法之一注册自定义反应流,以便在删除服务实例的各个阶段运行。spring-doc.cn

4.4. 服务实例运行状态检索

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

平台会轮询 Service Broker 的此方法,以查找正在进行异步操作的服务实例,直到 Service Broker 指示操作已成功完成或发生故障。spring-doc.cn

4.4.1. 事件注册表

可以通过利用事件进一步自定义服务实例上次操作请求。 为此,请执行以下操作:spring-doc.cn

  1. 自动装配 AsyncOperationServiceInstanceEventFlowRegistry Bean。spring-doc.cn

  2. 使用 addInitializationFlow()、addCompletionFlow() addErrorFlow() 方法之一注册自定义反应流,以便在上次操作检索的各个阶段运行。spring-doc.cn

4.5. 服务实例检索

如果该字段在服务目录中设置为 ,则 Service Broker 必须提供 getServiceInstance() 方法的实现。 否则,平台永远不会调用此方法,并且可以使用接口中的默认实现。instances_retrievabletruespring-doc.cn

Service Broker 负责维护支持检索操作所需的任何服务实例状态。spring-doc.cn

4.6. 示例实现

以下示例显示了一个服务实例实现:spring-doc.cn

package com.example.servicebroker;

import java.util.Map;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationRequest;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationResponse;
import org.springframework.cloud.servicebroker.model.instance.GetServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.GetServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.OperationState;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.service.ServiceInstanceService;
import org.springframework.stereotype.Service;

@Service
public class ExampleServiceInstanceService implements ServiceInstanceService {

	@Override
	public Mono<CreateServiceInstanceResponse> createServiceInstance(CreateServiceInstanceRequest request) {
		String serviceInstanceId = request.getServiceInstanceId();
		String planId = request.getPlanId();
		Map<String, Object> parameters = request.getParameters();

		//
		// perform the steps necessary to initiate the asynchronous
		// provisioning of all necessary resources
		//

		String dashboardUrl = ""; /* construct a dashboard URL */

		return Mono.just(CreateServiceInstanceResponse.builder()
				.dashboardUrl(dashboardUrl)
				.async(true)
				.build());
	}

	@Override
	public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceInstanceRequest request) {
		String serviceInstanceId = request.getServiceInstanceId();
		String planId = request.getPlanId();
		String previousPlan = request.getPreviousValues().getPlanId();
		Map<String, Object> parameters = request.getParameters();

		//
		// perform the steps necessary to initiate the asynchronous
		// updating of all necessary resources
		//

		return Mono.just(UpdateServiceInstanceResponse.builder()
				.async(true)
				.build());
	}

	@Override
	public Mono<DeleteServiceInstanceResponse> deleteServiceInstance(DeleteServiceInstanceRequest request) {
		String serviceInstanceId = request.getServiceInstanceId();
		String planId = request.getPlanId();

		//
		// perform the steps necessary to initiate the asynchronous
		// deletion of all provisioned resources
		//

		return Mono.just(DeleteServiceInstanceResponse.builder()
				.async(true)
				.build());
	}

	@Override
	public Mono<GetServiceInstanceResponse> getServiceInstance(GetServiceInstanceRequest request) {
		String serviceInstanceId = request.getServiceInstanceId();

		//
		// retrieve the details of the specified service instance
		//

		String dashboardUrl = ""; /* retrieve dashboard URL */

		return Mono.just(GetServiceInstanceResponse.builder()
				.dashboardUrl(dashboardUrl)
				.build());
	}

	@Override
	public Mono<GetLastServiceOperationResponse> getLastOperation(GetLastServiceOperationRequest request) {
		String serviceInstanceId = request.getServiceInstanceId();

		//
		// determine the status of the operation in progress
		//

		return Mono.just(GetLastServiceOperationResponse.builder()
				.operationState(OperationState.SUCCEEDED)
				.build());
	}
}

4.7. 事件流配置示例

有多种方法可以配置服务实例事件流。 一种选择是自动装配一个或多个注册表并直接与注册表交互。 另一个选项是为特定流定义 bean。 这些 bean 将被自动识别并添加到相应的注册表中。 最后一个选项是声明一个新的注册表 bean。 但是,请注意,定义新的注册表 Bean 会覆盖提供的自动配置。spring-doc.cn

4.7.1. 选项 1:Autowire 注册表

以下示例显示了服务实例事件流的配置:spring-doc.cn

package com.example.servicebroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationRequest;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationResponse;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.service.events.AsyncOperationServiceInstanceEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.CreateServiceInstanceEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.DeleteServiceInstanceEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.UpdateServiceInstanceEventFlowRegistry;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceInitializationFlow;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ExampleServiceInstanceEventFlowsConfiguration {

	private final CreateServiceInstanceEventFlowRegistry createRegistry;

	private final UpdateServiceInstanceEventFlowRegistry updateRegistry;

	private final DeleteServiceInstanceEventFlowRegistry deleteRegistry;

	private final AsyncOperationServiceInstanceEventFlowRegistry asyncRegistry;

	public ExampleServiceInstanceEventFlowsConfiguration(CreateServiceInstanceEventFlowRegistry createRegistry,
			UpdateServiceInstanceEventFlowRegistry updateRegistry,
			DeleteServiceInstanceEventFlowRegistry deleteRegistry,
			AsyncOperationServiceInstanceEventFlowRegistry asyncRegistry) {
		this.createRegistry = createRegistry;
		this.updateRegistry = updateRegistry;
		this.deleteRegistry = deleteRegistry;
		this.asyncRegistry = asyncRegistry;

		prepareCreateEventFlows()
				.then(prepareUpdateEventFlows())
				.then(prepareDeleteEventFlows())
				.then(prepareLastOperationEventFlows())
				.subscribe();
	}

	private Mono<Void> prepareCreateEventFlows() {
		return Mono.just(createRegistry)
				.map(registry -> registry.addInitializationFlow(new CreateServiceInstanceInitializationFlow() {
					@Override
					public Mono<Void> initialize(CreateServiceInstanceRequest request) {
						//
						// do something before the instance is created
						//
						return Mono.empty();
					}
				})
						.then(registry.addCompletionFlow(new CreateServiceInstanceCompletionFlow() {
							@Override
							public Mono<Void> complete(CreateServiceInstanceRequest request,
									CreateServiceInstanceResponse response) {
								//
								// do something after the instance is created
								//
								return Mono.empty();
							}
						}))
						.then(registry.addErrorFlow(new CreateServiceInstanceErrorFlow() {
							@Override
							public Mono<Void> error(CreateServiceInstanceRequest request, Throwable t) {
								//
								// do something if an error occurs while creating an instance
								//
								return Mono.empty();
							}
						})))
				.then();
	}

	private Mono<Void> prepareUpdateEventFlows() {
		return Mono.just(updateRegistry)
				.map(registry -> registry.addInitializationFlow(new UpdateServiceInstanceInitializationFlow() {
					@Override
					public Mono<Void> initialize(UpdateServiceInstanceRequest request) {
						//
						// do something before the instance is updated
						//
						return Mono.empty();
					}
				})
						.then(registry.addCompletionFlow(new UpdateServiceInstanceCompletionFlow() {
							@Override
							public Mono<Void> complete(UpdateServiceInstanceRequest request,
									UpdateServiceInstanceResponse response) {
								//
								// do something after the instance is updated
								//
								return Mono.empty();
							}
						}))
						.then(registry.addErrorFlow(new UpdateServiceInstanceErrorFlow() {
							@Override
							public Mono<Void> error(UpdateServiceInstanceRequest request, Throwable t) {
								//
								// do something if an error occurs while updating an instance
								//
								return Mono.empty();
							}
						})))
				.then();
	}

	private Mono<Void> prepareDeleteEventFlows() {
		return Mono.just(deleteRegistry)
				.map(registry -> registry.addInitializationFlow(new DeleteServiceInstanceInitializationFlow() {
					@Override
					public Mono<Void> initialize(DeleteServiceInstanceRequest request) {
						//
						// do something before the instance is deleted
						//
						return Mono.empty();
					}
				})
						.then(registry.addCompletionFlow(new DeleteServiceInstanceCompletionFlow() {
							@Override
							public Mono<Void> complete(DeleteServiceInstanceRequest request,
									DeleteServiceInstanceResponse response) {
								//
								// do something after the instance is deleted
								//
								return Mono.empty();
							}
						}))
						.then(registry.addErrorFlow(new DeleteServiceInstanceErrorFlow() {
							@Override
							public Mono<Void> error(DeleteServiceInstanceRequest 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 AsyncOperationServiceInstanceInitializationFlow() {
					@Override
					public Mono<Void> initialize(GetLastServiceOperationRequest request) {
						//
						// do something before returning the last operation
						//
						return Mono.empty();
					}
				})
						.then(registry.addCompletionFlow(new AsyncOperationServiceInstanceCompletionFlow() {
							@Override
							public Mono<Void> complete(GetLastServiceOperationRequest request,
									GetLastServiceOperationResponse response) {
								//
								// do something after returning the last operation
								//
								return Mono.empty();
							}
						}))
						.then(registry.addErrorFlow(new AsyncOperationServiceInstanceErrorFlow() {
							@Override
							public Mono<Void> error(GetLastServiceOperationRequest request, Throwable t) {
								//
								// do something if an error occurs while processing the last operation response
								//
								return Mono.empty();
							}
						})))
				.then();
	}

}

4.7.2. 选项 2:事件流 Bean

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

package com.example.servicebroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationRequest;
import org.springframework.cloud.servicebroker.model.instance.GetLastServiceOperationResponse;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest;
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.AsyncOperationServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.CreateServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.DeleteServiceInstanceInitializationFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceCompletionFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceErrorFlow;
import org.springframework.cloud.servicebroker.service.events.flows.UpdateServiceInstanceInitializationFlow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ExampleServiceInstanceEventFlowsConfiguration2 {

	//
	// Create Service Instance flows
	//

	@Bean
	public CreateServiceInstanceInitializationFlow createServiceInstanceInitializationFlow() {
		return new CreateServiceInstanceInitializationFlow() {
			@Override
			public Mono<Void> initialize(CreateServiceInstanceRequest request) {
				//
				// do something before the instance is created
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public CreateServiceInstanceCompletionFlow createServiceInstanceCompletionFlow() {
		return new CreateServiceInstanceCompletionFlow() {
			@Override
			public Mono<Void> complete(CreateServiceInstanceRequest request,
					CreateServiceInstanceResponse response) {
				//
				// do something after the instance is created
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public CreateServiceInstanceErrorFlow createServiceInstanceErrorFlow() {
		return new CreateServiceInstanceErrorFlow() {
			@Override
			public Mono<Void> error(CreateServiceInstanceRequest request, Throwable t) {
				//
				// do something if an error occurs while creating an instance
				//
				return Mono.empty();
			}
		};
	}

	//
	// Update Service Instance flows
	//

	@Bean
	public UpdateServiceInstanceInitializationFlow updateServiceInstanceInitializationFlow() {
		return new UpdateServiceInstanceInitializationFlow() {
			@Override
			public Mono<Void> initialize(
					UpdateServiceInstanceRequest request) {
				//
				// do something before the instance is updated
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public UpdateServiceInstanceCompletionFlow updateServiceInstanceCompletionFlow() {
		return new UpdateServiceInstanceCompletionFlow() {
			@Override
			public Mono<Void> complete(UpdateServiceInstanceRequest request,
					UpdateServiceInstanceResponse response) {
				//
				// do something after the instance is updated
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public UpdateServiceInstanceErrorFlow updateServiceInstanceErrorFlow() {
		return new UpdateServiceInstanceErrorFlow() {
			@Override
			public Mono<Void> error(UpdateServiceInstanceRequest request, Throwable t) {
				//
				// do something if an error occurs while updating an instance
				//
				return Mono.empty();
			}
		};
	}

	//
	// Delete Service Instance flows
	//

	@Bean
	public DeleteServiceInstanceInitializationFlow deleteServiceInstanceInitializationFlow() {
		return new DeleteServiceInstanceInitializationFlow() {
			@Override
			public Mono<Void> initialize(
					DeleteServiceInstanceRequest request) {
				//
				// do something before the instance is deleted
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public DeleteServiceInstanceCompletionFlow deleteServiceInstanceCompletionFlow() {
		return new DeleteServiceInstanceCompletionFlow() {
			@Override
			public Mono<Void> complete(DeleteServiceInstanceRequest request,
					DeleteServiceInstanceResponse response) {
				//
				// do something after the instance is deleted
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public DeleteServiceInstanceErrorFlow deleteServiceInstanceErrorFlow() {
		return new DeleteServiceInstanceErrorFlow() {
			@Override
			public Mono<Void> error(DeleteServiceInstanceRequest request, Throwable t) {
				//
				// do something if an error occurs while deleting the instance
				//
				return Mono.empty();
			}
		};
	}

	//
	// Get Last Operation flows
	//

	@Bean
	public AsyncOperationServiceInstanceInitializationFlow getLastOperationInitializationFlow() {
		return new AsyncOperationServiceInstanceInitializationFlow() {
			@Override
			public Mono<Void> initialize(
					GetLastServiceOperationRequest request) {
				//
				// do something before getting the last operation
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public AsyncOperationServiceInstanceCompletionFlow getLastOperationCompletionFlow() {
		return new AsyncOperationServiceInstanceCompletionFlow() {
			@Override
			public Mono<Void> complete(GetLastServiceOperationRequest request,
					GetLastServiceOperationResponse response) {
				//
				// do something after getting the last operation
				//
				return Mono.empty();
			}
		};
	}

	@Bean
	public AsyncOperationServiceInstanceErrorFlow getLastOperationErrorFlow() {
		return new AsyncOperationServiceInstanceErrorFlow() {
			@Override
			public Mono<Void> error(GetLastServiceOperationRequest request, Throwable t) {
				//
				// do something if an error occurs while getting the last operation
				//
				return Mono.empty();
			}
		};
	}

}