4. 服务实例

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

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

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

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

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

4.1. 服务实例创建

Service Broker 必须提供createServiceInstance()方法。spring-doc.cadn.net.cn

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

4.1.1. 事件注册表

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

  1. 自动装配CreateServiceInstanceEventFlowRegistry豆。spring-doc.cadn.net.cn

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

4.2. 服务实例更新

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

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

4.2.1. 事件注册表

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

  1. 自动装配UpdateServiceInstanceEventFlowRegistry豆。spring-doc.cadn.net.cn

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

4.3. 服务实例删除

deleteServiceInstance()method 必须由 Service Broker 提供。spring-doc.cadn.net.cn

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

4.3.1. 事件注册中心

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

  1. 自动装配DeleteServiceInstanceEventFlowRegistry豆。spring-doc.cadn.net.cn

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

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

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

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

4.4.1. 事件注册表

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

  1. 自动装配AsyncOperationServiceInstanceEventFlowRegistry豆。spring-doc.cadn.net.cn

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

4.5. 服务实例检索

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

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

4.6. 示例实现

以下示例显示了一个服务实例实现:spring-doc.cadn.net.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. Example Event Flow Configuration

There are multiple ways to configure service instance 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.spring-doc.cadn.net.cn

4.7.1. Option 1: Autowire Registries

The following example shows a configuration for service instance event flows:spring-doc.cadn.net.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. Option 2: Event Flow Beans

Optionally, you can configure beans for the individual flows, as follows:spring-doc.cadn.net.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();
			}
		};
	}

}