brooklyn.entity.cloudfoundry.webapp.PaasWebAppCloudFoundryDriver.java Source code

Java tutorial

Introduction

Here is the source code for brooklyn.entity.cloudfoundry.webapp.PaasWebAppCloudFoundryDriver.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package brooklyn.entity.cloudfoundry.webapp;

import brooklyn.entity.Entity;
import brooklyn.entity.basic.Attributes;
import brooklyn.entity.cloudfoundry.PaasEntityCloudFoundryDriver;
import brooklyn.entity.cloudfoundry.services.CloudFoundryService;
import brooklyn.location.cloudfoundry.CloudFoundryPaasLocation;
import brooklyn.util.text.Strings;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.cloudfoundry.client.lib.domain.CloudApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

public abstract class PaasWebAppCloudFoundryDriver extends PaasEntityCloudFoundryDriver
        implements PaasWebAppDriver {

    public static final Logger log = LoggerFactory.getLogger(PaasWebAppCloudFoundryDriver.class);

    private String applicationUrl;
    private String applicationName;

    public PaasWebAppCloudFoundryDriver(CloudFoundryWebAppImpl entity, CloudFoundryPaasLocation location) {
        super(entity, location);
    }

    @Override
    protected void init() {
        super.init();
        initApplicationParameters();
    }

    @SuppressWarnings("unchecked")
    private void initApplicationParameters() {
        applicationName = getEntity().getConfig(CloudFoundryWebApp.APPLICATION_NAME);
        applicationUrl = getEntity().getConfig(CloudFoundryWebApp.APPLICATION_URL);
    }

    @Override
    public CloudFoundryWebAppImpl getEntity() {
        return (CloudFoundryWebAppImpl) super.getEntity();
    }

    protected String getApplicationUrl() {
        return applicationUrl;
    }

    protected String getApplicationName() {
        return applicationName;
    }

    public abstract String getBuildpack();

    @Override
    public boolean isRunning() {
        CloudApplication app = getClient().getApplication(applicationName);
        return (app != null) && app.getState().equals(CloudApplication.AppState.STARTED);
    }

    @Override
    public int getInstancesNumber() {
        CloudApplication app = getClient().getApplication(getApplicationName());
        return app.getInstances();
    }

    @Override
    public int getDisk() {
        CloudApplication app = getClient().getApplication(getApplicationName());
        return app.getDiskQuota();
    }

    @Override
    public int getMemory() {
        CloudApplication app = getClient().getApplication(getApplicationName());
        return app.getMemory();
    }

    @Override
    public void start() {
        super.start();

        preDeploy();
        deploy();
        preLaunch();
        launch();
        postLaunch();
    }

    public void preDeploy() {
    }

    public abstract void deploy();

    public void preLaunch() {
        manageServices();

        configureEnv();
    }

    private void manageServices() {
        List<Entity> config = getEntity().getConfig(CloudFoundryWebApp.NAMED_SERVICES);
        if (config != null) {
            for (Entity serviceEntityId : config) {
                manageService(serviceEntityId);
            }
        }
    }

    /*TODO RENAME Method. It could be represent that the service is bound and the service
     operation is called*/
    private void manageService(Entity rawEntity) {

        CloudFoundryService cloudFoundryService;
        if (rawEntity instanceof CloudFoundryService) {

            cloudFoundryService = (CloudFoundryService) rawEntity;

            String serviceName = cloudFoundryService.getConfig(CloudFoundryService.SERVICE_INSTANCE_NAME);

            if (!Strings.isEmpty(serviceName)) {
                bindingServiceToEntity(serviceName);
                setCredentialsOnService(cloudFoundryService);
                cloudFoundryService.operation(getEntity());
            } else {
                log.error("Trying to get service instance name from {}, but getting null", cloudFoundryService);
            }
        } else {
            log.error("The service entity {} is not available from the application {}",
                    new Object[] { rawEntity, getEntity() });

            throw new NoSuchElementException("No entity matching id " + rawEntity.getId()
                    + " in Management Context " + getEntity().getManagementContext()
                    + " during entity service binding " + getEntity().getId());
        }
    }

    private void bindingServiceToEntity(String serviceId) {
        getClient().bindService(applicationName, serviceId);
        log.info("The service {} was bound correctly to the application {}",
                new Object[] { serviceId, applicationName });

        updateVariableEnvironmentSensors();
        updateBoundServiceSensor(serviceId);
    }

    private void updateVariableEnvironmentSensors() {
        Map<String, Object> env = getClient().getApplicationEnvironment(applicationName);
        JsonObject envTree = new Gson().toJsonTree(env).getAsJsonObject();
        getEntity().setAttribute(CloudFoundryWebApp.VCAP_SERVICES,
                envTree.getAsJsonObject("system_env_json").getAsJsonObject("VCAP_SERVICES").toString());
    }

    protected void setCredentialsOnService(CloudFoundryService service) {
        service.setBindingCredentialsFromApp(getEntity());
    }

    //TODO it ma be renamed to updateBoundServicesSensor
    protected void updateBoundServiceSensor(String serviceId) {
        if (serviceIsBoundToCloudApplication(serviceId)) {
            List<String> currentBoundServices = getEntity().getAttribute(CloudFoundryWebApp.BOUND_SERVICES);
            currentBoundServices.add(serviceId);
            getEntity().setAttribute(CloudFoundryWebApp.BOUND_SERVICES, currentBoundServices);
        }
    }

    /**
     * Return if a service is bound to the cloud application. Checks the running application in
     * the cloud.
     * @param serviceId
     * @return
     */
    public boolean serviceIsBoundToCloudApplication(String serviceId) {
        return getClient().getApplication(applicationName).getServices().contains(serviceId);
    }

    public void launch() {
        getClient().startApplication(applicationName);
    }

    public void postLaunch() {
        CloudApplication application = getClient().getApplication(applicationName);
        String domainUri = application.getUris().get(0);
        getEntity().setAttribute(Attributes.MAIN_URI, URI.create(domainUri));
        getEntity().setAttribute(CloudFoundryWebApp.ROOT_URL, domainUri);

        /*getEntity().setAttribute(CloudFoundryWebApp.INSTANCES_NUM,
            application.getInstances());*/

        getEntity().setAttribute(CloudFoundryWebApp.MEMORY, application.getMemory());

        getEntity().setAttribute(CloudFoundryWebApp.DISK, application.getDiskQuota());
    }

    @Override
    public void restart() {
        // TODO: complete
    }

    @Override
    public void stop() {
        getClient().stopApplication(applicationName);
        deleteApplication();
    }

    @Override
    public void deleteApplication() {
        getClient().deleteApplication(applicationName);
    }

    protected String inferApplicationDomainUri(String name) {
        String defaultDomainName = getClient().getDefaultDomain().getName();
        return name + "-domain." + defaultDomainName;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void setEnv(String key, String value) {
        CloudApplication app = getClient().getApplication(applicationName);

        // app.setEnv() replaces the entire set of variables, so we need to add it externally.
        Map envAsMap = app.getEnvAsMap();
        envAsMap.put(key, value);
        app.setEnv(envAsMap);
        getClient().updateApplicationEnv(applicationName, envAsMap);
    }

    protected void configureEnv() {
        //TODO a sensor with the custom-environment variables?
        setEnv(getEntity().getConfig(CloudFoundryWebApp.ENV));
    }

    @SuppressWarnings("unchecked")
    void setEnv(Map<String, String> envs) {
        CloudApplication app = getClient().getApplication(applicationName);

        // app.setEnv() replaces the entire set of variables, so we need to add it externally.
        Map oldEnv = app.getEnvAsMap();
        oldEnv.putAll(envs);
        getClient().updateApplicationEnv(applicationName, oldEnv);
    }

    @Override
    public void changeInstancesNumber(int instancesNumber) {
        getClient().updateApplicationInstances(getApplicationName(), instancesNumber);
    }

    @Override
    public void updateApplicationDiskQuota(int diskQuota) {
        getClient().updateApplicationDiskQuota(getApplicationName(), diskQuota);
    }

    @Override
    public void updateApplicationMemory(int memory) {
        getClient().updateApplicationMemory(getApplicationName(), memory);
    }

}