/** * This file is part of CloudML [ http://cloudml.org ] * * Copyright (C) 2012 - SINTEF ICT * Contact: Franck Chauvel <franck.chauvel@sintef.no> * * Module: root * * CloudML is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * CloudML is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with CloudML. If not, see * <http://www.gnu.org/licenses/>. */ package org.cloudml.connectors; import org.cloudfoundry.client.lib.CloudCredentials; import org.cloudfoundry.client.lib.CloudFoundryClient; import org.cloudfoundry.client.lib.HttpProxyConfiguration; import org.cloudfoundry.client.lib.domain.*; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; import org.cloudfoundry.client.lib.rest.CloudControllerClient; import org.cloudfoundry.client.lib.rest.CloudControllerClientFactory; import org.springframework.security.oauth2.common.OAuth2AccessToken; /** * Created by ferrynico on 03/12/2014. */ public class CloudFoundryConnector implements PaaSConnector { private CloudControllerClient connectedClient; private static final int DEFAULT_MEMORY = 512; // MB private static final Logger journal = Logger.getLogger(CloudFoundryConnector.class.getName()); private String defaultDomainName; public CloudFoundryConnector(String APIEndPoint, String login, String passwd, String organization, String space){ try { URL cloudControllerUrl = URI.create(APIEndPoint).toURL(); journal.log(Level.INFO, ">> Connecting to CloudFoundry ..."); CloudControllerClientFactory cff=new CloudControllerClientFactory(null,true); connectedClient = cff.newCloudController(cloudControllerUrl, new CloudCredentials(login,passwd),organization,space); connectedClient.login(); defaultDomainName = connectedClient.getDefaultDomain().getName(); journal.log(Level.INFO, ">> Default domain name: "+defaultDomainName); } catch (MalformedURLException e) { journal.log(Level.SEVERE, e.getMessage()); } catch (Exception e) { journal.log(Level.SEVERE, e.getMessage()); } } public void logOut(){ connectedClient.logout(); } public CloudControllerClient getConnectedClient(){ return connectedClient; } private String computeAppUrl(String appName, String domainName) { return appName + "." + ((domainName.equals("") || domainName.equals(appName))? defaultDomainName : domainName); } @Override public String createEnvironmentWithWar(String applicationName, String domainName, String envName, String stackName, int minRam, String warFile, String versionLabel) { journal.log(Level.INFO, ">> Creating application ... "); List<String> uris = new ArrayList<String>(); uris.add(computeAppUrl(applicationName, domainName)); journal.log(Level.INFO, ">> App URI: "+computeAppUrl(applicationName, domainName)); Staging staging; if(stackName != null && !stackName.equals("")){ staging=new Staging(null, stackName); }else{ staging= new Staging(); } int mem=DEFAULT_MEMORY; if(minRam > 0) mem=minRam; List<String> serviceNames = new ArrayList<String>(); journal.log(Level.INFO, ">> Environment created ... "+staging); /*if(connectedClient.getApplication(applicationName) != null){ throw new IllegalStateException("Application name already used!"); }*/ connectedClient.createApplication(applicationName, staging, mem, uris, serviceNames); journal.log(Level.INFO, ">> Environment created ... "); CloudApplication app = connectedClient.getApplication(applicationName); journal.log(Level.INFO, ">> Application details: "+ app.getName() + ", URI: " + app.getUris().get(0)+ ", Memory: " +app.getMemory()); try { journal.log(Level.INFO, ">> Uploading application ... "); connectedClient.uploadApplication(applicationName,new File(warFile), null); journal.log(Level.INFO, ">> Starting application ... "); connectedClient.startApplication(app.getName()); } catch (IOException e) { journal.log(Level.SEVERE, e.getMessage()); } return computeAppUrl(applicationName, domainName); } public String getAppEndPoint(String appName){ return connectedClient.getApplication(appName).getUris().get(0); } @Override public void bindDbToApp(String appId, String dbId, String alias) { bindService(appId,dbId); } public void bindService(String appName, String serviceName){ if(checkIfApplicationExist(appName) && checkIfServiceExist(serviceName)){ connectedClient.bindService(appName, serviceName); } connectedClient.restartApplication(appName); } @Override public void setEnvVar(String appName, String nameVar, String val){ connectedClient.updateApplicationEnv(appName, Collections.singletonMap(nameVar, val)); CloudApplication ca=connectedClient.getApplication(appName); while(connectedClient.getApplicationInstances(ca) == null){ try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } connectedClient.restartApplication(appName); } private Boolean checkIfServiceExist(String serviceName){ return connectedClient.getService(serviceName) != null; } private Boolean checkIfApplicationExist(String appName){ return connectedClient.getApplication(appName) != null; } public List<CloudApplication> listApplications(){ return connectedClient.getApplications(); } private Boolean checkIfPlanExist(String planName, String serviceLabel){ for(CloudServicePlan csp : findCloudServiceOffering(serviceLabel).getCloudServicePlans()){ if(csp.getMeta().equals(serviceLabel)) return true; } return false; } private String findFreePlan(String serviceLabel){ for(CloudServicePlan csp : findCloudServiceOffering(serviceLabel).getCloudServicePlans()){ if(csp.isFree()) return csp.getName(); } return ""; } public void updateApplicationDisk(String appName, int size){ connectedClient.updateApplicationDiskQuota(appName, size); } public void updateApplicationMemory(String appName, int size){ connectedClient.updateApplicationMemory(appName, size); } public CloudServiceOffering findCloudServiceOffering(String label) { List<CloudServiceOffering> serviceOfferings = connectedClient.getServiceOfferings(); for (CloudServiceOffering so : serviceOfferings) { if (so.getLabel().equals(label)) { return so; } } return null; } @Override public void createDBInstance(String engine, String version, String dbInstanceIdentifier, String dbName, String username, String password, Integer allocatedSize, String dbInstanceClass, String securityGroup) { if(checkIfServiceExist(dbInstanceIdentifier)){ journal.log(Level.INFO, ">> A DB with this name already exist! "); return; } journal.log(Level.INFO, ">> Initializing DB ... "); CloudService service = new CloudService(CloudEntity.Meta.defaultMeta(), dbInstanceIdentifier); service.setLabel(engine); if(version == null) version = ""; if(!version.equals("") && checkIfPlanExist(version, engine)) service.setPlan(version); else service.setPlan(findFreePlan(engine)); connectedClient.createService(service); } @Override public String getDBEndPoint(String dbInstanceId, int timeout) { return null; } @Override public void uploadWar(String warFile, String versionLabel, String applicationName, String envName, int timeout) { try { journal.log(Level.INFO, ">> Uploading application ... "); connectedClient.uploadApplication(applicationName,new File(warFile), null); journal.log(Level.INFO, ">> Starting application ... "); connectedClient.startApplication(applicationName); } catch (IOException e) { journal.log(Level.SEVERE, e.getMessage()); } } @Override public void deleteApp(String name){ connectedClient.deleteApplication(name); } @Override public String createQueue(String name) { return null; } @Override public void deleteQueue(String name) { } @Override public List<String> listQueues() { return null; } @Override public void restoreDB(String host, String port, String dbUser, String dbPass, String dbName, String local_file) { } @Override public void configAppParameters(String applicationName, Map<String, String> params) { } }