package com.emc.ecs.servicebroker.service; import com.emc.ecs.servicebroker.EcsManagementClientException; import com.emc.ecs.servicebroker.model.ServiceDefinitionProxy; import com.emc.ecs.servicebroker.repository.ServiceInstanceBinding; import com.emc.ecs.servicebroker.repository.ServiceInstanceBindingRepository; import com.emc.ecs.servicebroker.repository.ServiceInstanceRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.servicebroker.exception.ServiceBrokerException; import org.springframework.cloud.servicebroker.exception.ServiceInstanceBindingDoesNotExistException; 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.service.ServiceInstanceBindingService; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; import javax.xml.bind.JAXBException; import java.io.IOException; import java.util.Map; @Service public class EcsServiceInstanceBindingService implements ServiceInstanceBindingService { private static final String NAMESPACE = "namespace"; private static final String BUCKET = "bucket"; private static final Logger LOG = LoggerFactory.getLogger(EcsServiceInstanceBindingService.class); private static final String NO_SERVICE_MATCHING_TYPE = "No service matching type: "; private static final String SERVICE_TYPE = "service-type"; @Autowired private EcsService ecs; @Autowired private ServiceInstanceBindingRepository repository; @Autowired private ServiceInstanceRepository instanceRepo; public EcsServiceInstanceBindingService() { super(); } @Override public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(CreateServiceInstanceBindingRequest request) throws ServiceBrokerException { try { BindingWorkflow workflow = getWorkflow(request); LOG.info("creating binding"); workflow.checkIfUserExists(); String secretKey = workflow.createBindingUser(); LOG.info("building binding response"); Map<String, Object> credentials = workflow.getCredentials(secretKey, request.getParameters()); ServiceInstanceBinding binding = workflow.getBinding(credentials); LOG.info("saving binding..."); repository.save(binding); LOG.info("binding saved."); return Mono.just(workflow.getResponse(credentials)); } catch (IOException | JAXBException | EcsManagementClientException e) { throw new ServiceBrokerException(e); } } @Override public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(DeleteServiceInstanceBindingRequest request) throws ServiceBrokerException { String bindingId = request.getBindingId(); try { BindingWorkflow workflow = getWorkflow(request) .withDeleteRequest(request); LOG.info("looking up binding: " + bindingId); ServiceInstanceBinding binding = repository.find(bindingId); if (binding == null) throw new ServiceInstanceBindingDoesNotExistException(bindingId); LOG.info("binding found: " + bindingId); workflow.removeBinding(binding); LOG.info("deleting from repository" + bindingId); repository.delete(bindingId); return Mono.just(DeleteServiceInstanceBindingResponse.builder() .async(false) .build()); } catch (Exception e) { LOG.error("Error deleting binding: " + e); throw new ServiceBrokerException(e); } } private BindingWorkflow getWorkflow(DeleteServiceInstanceBindingRequest deleteRequest) throws EcsManagementClientException, IOException { if (isRemoteConnectBinding(deleteRequest)) return new RemoteConnectBindingWorkflow(instanceRepo, ecs); ServiceDefinitionProxy service = ecs.lookupServiceDefinition(deleteRequest.getServiceDefinitionId()); return getWorkflow(service).withDeleteRequest(deleteRequest); } private BindingWorkflow getWorkflow(CreateServiceInstanceBindingRequest createRequest) throws EcsManagementClientException, IOException { if (isRemoteConnectBinding(createRequest)) return new RemoteConnectBindingWorkflow(instanceRepo, ecs) .withCreateRequest(createRequest); ServiceDefinitionProxy service = ecs.lookupServiceDefinition(createRequest.getServiceDefinitionId()); return getWorkflow(service).withCreateRequest(createRequest); } private BindingWorkflow getWorkflow(ServiceDefinitionProxy service) throws IOException { String serviceType = (String) service.getServiceSettings().get(SERVICE_TYPE); switch (serviceType) { case NAMESPACE: return new NamespaceBindingWorkflow(instanceRepo, ecs, service); case BUCKET: return new BucketBindingWorkflow(instanceRepo, ecs); default: throw new ServiceBrokerException(NO_SERVICE_MATCHING_TYPE + serviceType); } } private boolean isRemoteConnectBinding(DeleteServiceInstanceBindingRequest deleteRequest) throws IOException { String bindingId = deleteRequest.getBindingId(); ServiceInstanceBinding binding = repository.find(bindingId); if (binding == null) throw new ServiceInstanceBindingDoesNotExistException(bindingId); return isRemoteConnectBinding(binding.getParameters()); } private Boolean isRemoteConnectBinding(CreateServiceInstanceBindingRequest createRequest) { Map<String, Object> parameters = createRequest.getParameters(); return isRemoteConnectBinding(parameters); } private boolean isRemoteConnectBinding(Map<String, Object> parameters) { return (parameters != null) && parameters.containsKey("remote_connection") && (Boolean) parameters.get("remote_connection"); } }