All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudfoundry.multiapps.controller.process.util.ServiceBindingParametersGetter Maven / Gradle / Ivy

There is a newer version: 1.183.0
Show newest version
package org.cloudfoundry.multiapps.controller.process.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import org.cloudfoundry.multiapps.common.SLException;
import org.cloudfoundry.multiapps.common.util.JsonUtil;
import org.cloudfoundry.multiapps.controller.client.lib.domain.BindingDetails;
import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudApplicationExtended;
import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended;
import org.cloudfoundry.multiapps.controller.core.helpers.MtaArchiveElements;
import org.cloudfoundry.multiapps.controller.core.security.serialization.SecureSerialization;
import org.cloudfoundry.multiapps.controller.persistence.services.FileService;
import org.cloudfoundry.multiapps.controller.persistence.services.FileStorageException;
import org.cloudfoundry.multiapps.controller.process.Messages;
import org.cloudfoundry.multiapps.controller.process.steps.ProcessContext;
import org.cloudfoundry.multiapps.controller.process.variables.Variables;
import org.cloudfoundry.multiapps.mta.handlers.ArchiveHandler;
import org.cloudfoundry.multiapps.mta.util.NameUtil;
import org.cloudfoundry.multiapps.mta.util.PropertiesUtil;
import org.springframework.http.HttpStatus;

import com.sap.cloudfoundry.client.facade.CloudControllerClient;
import com.sap.cloudfoundry.client.facade.CloudOperationException;
import com.sap.cloudfoundry.client.facade.domain.CloudApplication;
import com.sap.cloudfoundry.client.facade.domain.CloudServiceBinding;

public class ServiceBindingParametersGetter {

    private final ProcessContext context;
    private final ArchiveEntryExtractor archiveEntryExtractor;
    private final long maxManifestSize;
    private final FileService fileService;

    public ServiceBindingParametersGetter(ProcessContext context, ArchiveEntryExtractor archiveEntryExtractor, long maxManifestSize,
                                          FileService fileService) {
        this.context = context;
        this.archiveEntryExtractor = archiveEntryExtractor;
        this.maxManifestSize = maxManifestSize;
        this.fileService = fileService;
    }

    public Map getServiceBindingParametersFromMta(CloudApplicationExtended app, String serviceName) {
        Optional service = getService(context.getVariable(Variables.SERVICES_TO_BIND), serviceName);
        if (service.isEmpty()) {
            return Collections.emptyMap();
        }

        Map fileProvidedBindingParameters = getFileProvidedBindingParameters(app.getModuleName(), service.get());
        Map descriptorProvidedBindingParameters = getDescriptorProvidedBindingParameters(app, service.get());
        Map bindingParameters = PropertiesUtil.mergeExtensionProperties(fileProvidedBindingParameters,
                                                                                        descriptorProvidedBindingParameters);
        context.getStepLogger()
               .debug(Messages.BINDING_PARAMETERS_FOR_APPLICATION, app.getName(), SecureSerialization.toJson(bindingParameters));
        return bindingParameters;
    }

    private Optional getService(List services, String serviceName) {
        return services.stream()
                       .filter(service -> service.getName()
                                                 .equals(serviceName))
                       .findFirst();
    }

    private Map getFileProvidedBindingParameters(String moduleName, CloudServiceInstanceExtended service) {
        String requiredDependencyName = NameUtil.getPrefixedName(moduleName, service.getResourceName(),
                                                                 org.cloudfoundry.multiapps.controller.core.Constants.MTA_ELEMENT_SEPARATOR);
        return getFileProvidedBindingParameters(requiredDependencyName);
    }

    private Map getFileProvidedBindingParameters(String requiredDependencyName) {
        MtaArchiveElements mtaArchiveElements = context.getVariable(Variables.MTA_ARCHIVE_ELEMENTS);
        String fileName = mtaArchiveElements.getRequiredDependencyFileName(requiredDependencyName);
        if (fileName == null) {
            return Collections.emptyMap();
        }
        String spaceGuid = context.getRequiredVariable(Variables.SPACE_GUID);
        String appArchiveId = context.getRequiredVariable(Variables.APP_ARCHIVE_ID);

        // TODO: backwards compatibility for one tact
        List archiveEntriesWithStreamPositions = context.getVariable(Variables.ARCHIVE_ENTRIES_POSITIONS);
        if (archiveEntriesWithStreamPositions == null) {
            try {
                return fileService.processFileContent(spaceGuid, appArchiveId, appArchiveStream -> {
                    InputStream fileStream = ArchiveHandler.getInputStream(appArchiveStream, fileName, maxManifestSize);
                    return JsonUtil.convertJsonToMap(fileStream);
                });
            } catch (FileStorageException e) {
                throw new SLException(e, e.getMessage());
            }
        }
        // TODO: backwards compatibility for one tact

        ArchiveEntryWithStreamPositions archiveEntryWithStreamPositions = ArchiveEntryExtractorUtil.findEntry(fileName,
                                                                                                              context.getVariable(Variables.ARCHIVE_ENTRIES_POSITIONS));
        byte[] serviceBindingParametersFileContent = archiveEntryExtractor.extractEntryBytes(ImmutableFileEntryProperties.builder()
                                                                                                                         .guid(appArchiveId)
                                                                                                                         .name(archiveEntryWithStreamPositions.getName())
                                                                                                                         .spaceGuid(context.getRequiredVariable(Variables.SPACE_GUID))
                                                                                                                         .maxFileSizeInBytes(maxManifestSize)
                                                                                                                         .build(),
                                                                                             archiveEntryWithStreamPositions);
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serviceBindingParametersFileContent)) {
            return JsonUtil.convertJsonToMap(byteArrayInputStream);
        } catch (IOException e) {
            throw new SLException(e, Messages.ERROR_RETRIEVING_MTA_REQUIRED_DEPENDENCY_CONTENT, fileName);
        }
    }

    private Map getDescriptorProvidedBindingParameters(CloudApplicationExtended app, CloudServiceInstanceExtended service) {
        BindingDetails bindingDetails = getDescriptorProvidedBindingParametersAndBindingName(app, service);
        return (bindingDetails != null && bindingDetails.getConfig() != null) ? bindingDetails.getConfig() : Collections.emptyMap();
    }

    private BindingDetails getDescriptorProvidedBindingParametersAndBindingName(CloudApplicationExtended app,
                                                                                CloudServiceInstanceExtended service) {
        return app.getBindingParameters()
                  .get(service.getResourceName());
    }

    public String getDescriptorProvidedBindingName(CloudApplicationExtended app, String serviceName) {
        Optional service = getService(context.getVariable(Variables.SERVICES_TO_BIND), serviceName);
        if (service.isEmpty()) {
            return null;
        }
        BindingDetails bindingDetails = getDescriptorProvidedBindingParametersAndBindingName(app, service.get());
        return (bindingDetails != null && bindingDetails.getBindingName() != null) ? bindingDetails.getBindingName() : null;
    }

    public Map getServiceBindingParametersFromExistingInstance(CloudApplication application, String serviceName) {
        CloudControllerClient client = context.getControllerClient();
        UUID serviceGuid = client.getRequiredServiceInstanceGuid(serviceName);
        CloudServiceBinding serviceBinding = client.getServiceBindingForApplication(application.getGuid(), serviceGuid);
        if (serviceBinding == null) {
            throw new SLException(Messages.SERVICE_INSTANCE_0_NOT_BOUND_TO_APP_1, serviceName, application.getName());
        }

        try {
            return client.getServiceBindingParameters(serviceBinding.getGuid());
        } catch (CloudOperationException e) {
            if (HttpStatus.NOT_IMPLEMENTED == e.getStatusCode() || HttpStatus.BAD_REQUEST == e.getStatusCode()) {
                // ignore 501 and 400 error codes from service brokers
                context.getStepLogger()
                       .warnWithoutProgressMessage(Messages.CANNOT_RETRIEVE_PARAMETERS_OF_BINDING_BETWEEN_APPLICATION_0_AND_SERVICE_INSTANCE_1,
                                                   application.getName(), serviceName);
                return null;
            } else if (HttpStatus.BAD_GATEWAY == e.getStatusCode()) {
                // TODO: this is a temporary fix for external error code mapping leading to incorrect 502 errors
                context.getStepLogger()
                       .warnWithoutProgressMessage(Messages.CANNOT_RETRIEVE_PARAMETERS_OF_BINDING_BETWEEN_APPLICATION_0_AND_SERVICE_INSTANCE_1_FIX,
                                                   application.getName(), serviceName);
                return null;
            }
            throw e;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy