package org.springframework.cloud.cloudfoundry; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.ServiceLoader; import org.springframework.cloud.AbstractCloudConnector; import org.springframework.cloud.CloudException; import org.springframework.cloud.FallbackServiceInfoCreator; import org.springframework.cloud.app.ApplicationInstanceInfo; import org.springframework.cloud.service.BaseServiceInfo; import org.springframework.cloud.util.EnvironmentAccessor; import com.fasterxml.jackson.databind.ObjectMapper; /** * * @author Ramnivas Laddad * @author Scott Frederick */ public class CloudFoundryConnector extends AbstractCloudConnector<Map<String,Object>> { private ObjectMapper objectMapper = new ObjectMapper(); private EnvironmentAccessor environment = new EnvironmentAccessor(); private ApplicationInstanceInfoCreator applicationInstanceInfoCreator = new ApplicationInstanceInfoCreator(); private Iterable<ServiceDataPostProcessor> serviceDataPostProcessors; @SuppressWarnings({ "unchecked", "rawtypes" }) public CloudFoundryConnector() { super((Class) CloudFoundryServiceInfoCreator.class); scanServiceDataPostProcessors(); } @Override public boolean isInMatchingCloud() { return environment.getEnvValue("VCAP_APPLICATION") != null; } @Override public ApplicationInstanceInfo getApplicationInstanceInfo() { try { @SuppressWarnings("unchecked") Map<String, Object> rawApplicationInstanceInfo = objectMapper.readValue(environment.getEnvValue("VCAP_APPLICATION"), Map.class); return applicationInstanceInfoCreator.createApplicationInstanceInfo(rawApplicationInstanceInfo); } catch (Exception e) { throw new CloudException(e); } } /* package for testing purpose */ void setCloudEnvironment(EnvironmentAccessor environment) { this.environment = environment; } /** * Return object representation of the VCAP_SERVICES environment variable * <p> * Returns a list whose element is a map with service attributes. * </p> * @return parsed service data */ @SuppressWarnings("unchecked") protected List<Map<String,Object>> getServicesData() { String servicesString = environment.getEnvValue("VCAP_SERVICES"); CloudFoundryRawServiceData rawServices = new CloudFoundryRawServiceData(); if (servicesString != null && servicesString.length() > 0) { try { rawServices = objectMapper.readValue(servicesString, CloudFoundryRawServiceData.class); } catch (Exception e) { throw new CloudException(e); } } for (ServiceDataPostProcessor postProcessor : serviceDataPostProcessors) { rawServices = postProcessor.process(rawServices); } List<Map<String, Object>> flatServices = new ArrayList<Map<String, Object>>(); for (Map.Entry<String, List<Map<String,Object>>> entry : rawServices.entrySet()) { flatServices.addAll(entry.getValue()); } return flatServices; } @Override protected FallbackServiceInfoCreator<BaseServiceInfo,Map<String,Object>> getFallbackServiceInfoCreator() { return new CloudFoundryFallbackServiceInfoCreator(); } private void scanServiceDataPostProcessors() { serviceDataPostProcessors = ServiceLoader.load(ServiceDataPostProcessor.class); } } class CloudFoundryFallbackServiceInfoCreator extends FallbackServiceInfoCreator<BaseServiceInfo,Map<String,Object>> { @Override public BaseServiceInfo createServiceInfo(Map<String,Object> serviceData) { String id = (String) serviceData.get("name"); return new BaseServiceInfo(id); } }