diff --git a/bin/fogbow-cloud-config.cfg b/bin/fogbow-cloud-config.cfg new file mode 100644 index 00000000..ea4f77ee --- /dev/null +++ b/bin/fogbow-cloud-config.cfg @@ -0,0 +1,9 @@ +#cloud-config +users: + - name: #TOKEN_MANAGER_SSH_USER# + chpasswd: {expire: False} + ssh_pwauth: True + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - #TOKEN_MANAGER_SSH_PUBLIC_KEY# \ No newline at end of file diff --git a/manager.conf.example b/manager.conf.example index 4bedbabb..dbc9ac4a 100644 --- a/manager.conf.example +++ b/manager.conf.example @@ -6,13 +6,20 @@ xmpp_port=5347 rendezvous_jid=rendezvous.test.com greensitter_jid=greensitter.test.com +# That flavor specification will be transformed into requirements. +flavor_fogbow_small={mem=512, cpu=1} +flavor_fogbow_medium={mem=1024, cpu=2} +flavor_fogbow_large={mem=2048, cpu=4} + +# Compute Opennebula compute_class=org.fogbowcloud.manager.core.plugins.opennebula.OpenNebulaComputePlugin compute_one_url=http://localhost:2633/RPC2 -compute_one_flavor_small={mem=128, cpu=1} -compute_one_flavor_medium={mem=256, cpu=2} -compute_one_flavor_large={mem=512, cpu=4} compute_one_network_id=1 +# Setting used to find the correct flavor according to informed templates. +# types :all or specific templates(template1,template2) +compute_one_templates=all + # Settings used by ONE compute plugin to register new images in the cloud # ID of datastore to register the image compute_one_datastore_id=1 @@ -27,17 +34,25 @@ compute_one_ssh_key_file=/home/fogbow/.ssh/id_rsa # Set the directory to copy images in remote host compute_one_ssh_target_temp_folder=/tmp/images +# Compute Openstack OCCI compute_class=org.fogbowcloud.manager.core.plugins.openstack.OpenStackOCCIComputePlugin compute_openstack_v2api_url=http://localhost:8182 compute_occi_url=http://localhost:8182 -compute_occi_flavor_small=m1-small -compute_occi_flavor_medium=m1-medium -compute_occi_flavor_large=m1-large compute_occi_os_scheme=http://schemas.openstack.org/template/os# compute_occi_instance_scheme=http://schemas.openstack.org/compute/instance# compute_occi_resource_scheme=http://schemas.openstack.org/template/resource# compute_occi_network_id=ea51ed0c-0e8a-448d-8202-c79777109ffe +# Compute Opennebula OCCI +compute_class=org.fogbowcloud.manager.core.plugins.opennebula.OpenNebulaOCCIComputePlugin +compute_one_url=http://localhost:2633/RPC2 +compute_occi_url=http://localhost:3000 +compute_occi_template_scheme=http://occi.localhost/occi/infrastructure/os_tpl# +compute_occi_resource_scheme=http://schema.fedcloud.egi.eu/occi/infrastructure/resource_tpl# +compute_occi_flavors_small={cpu=1,mem=512} +compute_occi_flavors_medium={cpu=2,mem=1024} +compute_occi_flavors_large={cpu=4,mem=2048} + # If you are using the EgiImageStoragePlugin image_storage_class=org.fogbowcloud.manager.core.plugins.imagestorage.egi.EgiImageStoragePlugin image_storage_egi_base_url=http://lsd.ufcg.edu.br/~user/vm/ @@ -61,21 +76,22 @@ image_storage_static_fogbow-ubuntu-1204=81765250-a4e4-440d-a215-43c9c0849120 member_picker_class=org.fogbowcloud.manager.core.RoundRobinMemberPicker #If you are using NoFMemberPicker or NoFPrioritizationPlugin classes nof_trustworthy=false +nof_prioritize_local=true local_prioritization_plugin_class=org.fogbowcloud.manager.core.plugins.prioritization.FCFSPrioritizationPlugin remote_prioritization_plugin_class=org.fogbowcloud.manager.core.plugins.prioritization.nof.NoFPrioritizationPlugin +# Compute Openstack compute_class=org.fogbowcloud.manager.core.plugins.openstack.OpenStackNovaV2ComputePlugin compute_novav2_url=http://localhost:8774 compute_glancev2_url=http://localhost:9292 -compute_novav2_flavor_small=1 -compute_novav2_flavor_medium=2 -compute_novav2_flavor_large=3 compute_novav2_network_id=ea51ed0c-0e8a-448d-8202-c79777109ffe +# Local identity local_identity_class=org.fogbowcloud.manager.core.plugins.openstack.KeystoneIdentityPlugin local_identity_url=http://localhost:5000 +# Federation identity federation_authorization_class=org.fogbowcloud.manager.core.plugins.common.AllowAllAuthorizationPlugin federation_identity_class=org.fogbowcloud.manager.core.plugins.openstack.KeystoneIdentityPlugin federation_identity_url=http://localhost:5000 diff --git a/pom.xml b/pom.xml index 43a98143..4085c5dd 100644 --- a/pom.xml +++ b/pom.xml @@ -210,6 +210,16 @@ sshj 0.8.1 + + javax.mail + mail + 1.4 + + + com.google.guava + guava + r09 + com.h2database h2 @@ -220,7 +230,6 @@ mail 1.4 - diff --git a/src/main/java/org/fogbowcloud/manager/Main.java b/src/main/java/org/fogbowcloud/manager/Main.java index dde9c064..55713ad0 100644 --- a/src/main/java/org/fogbowcloud/manager/Main.java +++ b/src/main/java/org/fogbowcloud/manager/Main.java @@ -19,9 +19,9 @@ import org.fogbowcloud.manager.core.plugins.ImageStoragePlugin; import org.fogbowcloud.manager.core.plugins.PrioritizationPlugin; import org.fogbowcloud.manager.core.plugins.accounting.FCUAccountingPlugin; -import org.fogbowcloud.manager.core.plugins.benchmarking.FCUStaticBenchmarkingPlugin; -import org.fogbowcloud.manager.core.plugins.prioritization.TwoFoldPrioritizationPlugin; +import org.fogbowcloud.manager.core.plugins.benchmarking.VanillaBenchmarkingPlugin; import org.fogbowcloud.manager.core.plugins.imagestorage.egi.EgiImageStoragePlugin; +import org.fogbowcloud.manager.core.plugins.prioritization.TwoFoldPrioritizationPlugin; import org.fogbowcloud.manager.occi.OCCIApplication; import org.fogbowcloud.manager.occi.core.ResourceRepository; import org.fogbowcloud.manager.xmpp.ManagerXmppComponent; @@ -109,7 +109,7 @@ public static void main(String[] args) throws Exception { benchmarkingPlugin = (BenchmarkingPlugin) createInstance( ConfigurationConstants.BENCHMARKING_PLUGIN_CLASS_KEY, properties); } catch (Exception e) { - benchmarkingPlugin = new FCUStaticBenchmarkingPlugin(properties); + benchmarkingPlugin = new VanillaBenchmarkingPlugin(properties); LOGGER.warn("Benchmarking plugin not specified in properties. Using the default one.", e); } diff --git a/src/main/java/org/fogbowcloud/manager/core/ConfigurationConstants.java b/src/main/java/org/fogbowcloud/manager/core/ConfigurationConstants.java index efee043b..d1c1c0fb 100644 --- a/src/main/java/org/fogbowcloud/manager/core/ConfigurationConstants.java +++ b/src/main/java/org/fogbowcloud/manager/core/ConfigurationConstants.java @@ -41,10 +41,10 @@ public class ConfigurationConstants { public static final String ASYNC_REQUEST_WAITING_INTERVAL_KEY = "asyn_request_waiting_interval"; //ssh properties TODO change these properties names to TOKEN_HOST_... - public static final String SSH_PRIVATE_HOST_KEY = "ssh_tunnel_private_host"; - public static final String SSH_PUBLIC_HOST_KEY = "ssh_tunnel_public_host"; - public static final String SSH_HOST_PORT_KEY = "ssh_tunnel_host_port"; - public static final String SSH_HOST_HTTP_PORT_KEY = "ssh_tunnel_host_http_port"; + public static final String TUNNEL_SSH_PRIVATE_HOST_KEY = "ssh_tunnel_private_host"; + public static final String TUNNEL_SSH_PUBLIC_HOST_KEY = "ssh_tunnel_public_host"; + public static final String TUNNEL_SSH_HOST_PORT_KEY = "ssh_tunnel_host_port"; + public static final String TUNNEL_SSH_HOST_HTTP_PORT_KEY = "ssh_tunnel_host_http_port"; //voms public static final String VOMS_PATH_VOMSES = "path_vomses"; @@ -59,6 +59,10 @@ public class ConfigurationConstants { public static final String MAX_WHOISALIVE_MANAGER_COUNT = "max_whoisalive_manager_count"; public static final String IMAGE_STORAGE_PLUGIN_CLASS = "image_storage_class"; + public static final String SSH_PUBLIC_KEY_PATH = "ssh_public_key"; + public static final String SSH_PRIVATE_KEY_PATH = "ssh_private_key"; + public static final String SSH_COMMON_USER = "ssh_common_user"; + //benchmarking public static final String BENCHMARKING_PLUGIN_CLASS_KEY = "benchmarking_class"; diff --git a/src/main/java/org/fogbowcloud/manager/core/ManagerController.java b/src/main/java/org/fogbowcloud/manager/core/ManagerController.java index a6834f91..fdf0192e 100644 --- a/src/main/java/org/fogbowcloud/manager/core/ManagerController.java +++ b/src/main/java/org/fogbowcloud/manager/core/ManagerController.java @@ -1,5 +1,8 @@ package org.fogbowcloud.manager.core; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -17,6 +20,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import javax.mail.MessagingException; + +import net.schmizz.sshj.connection.channel.direct.Session.Command; + +import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; @@ -36,6 +44,7 @@ import org.fogbowcloud.manager.core.plugins.ImageStoragePlugin; import org.fogbowcloud.manager.core.plugins.PrioritizationPlugin; import org.fogbowcloud.manager.core.plugins.accounting.ResourceUsage; +import org.fogbowcloud.manager.core.plugins.util.SshHelper; import org.fogbowcloud.manager.occi.core.Category; import org.fogbowcloud.manager.occi.core.ErrorType; import org.fogbowcloud.manager.occi.core.OCCIException; @@ -57,16 +66,21 @@ public class ManagerController { + public static final String DEFAULT_COMMON_SSH_USER = "fogbow"; + private static final String PROP_MAX_WHOISALIVE_MANAGER_COUNT = "max_whoisalive_manager_count"; private static final Logger LOGGER = Logger.getLogger(ManagerController.class); + public static final long DEFAULT_SCHEDULER_PERIOD = 30000; // 30 seconds private static final long DEFAULT_TOKEN_UPDATE_PERIOD = 300000; // 5 minutes protected static final int DEFAULT_ASYNC_REQUEST_WAITING_INTERVAL = 300000; // 5 minutes private static final long DEFAULT_INSTANCE_MONITORING_PERIOD = 120000; // 2 minutes private static final long DEFAULT_SERVED_REQUEST_MONITORING_PERIOD = 120000; // 2 minutes private static final long DEFAULT_GARBAGE_COLLECTOR_PERIOD = 240000; // 4 minutes + private static final long DEFAULT_INSTANCE_IP_MONITORING_PERIOD = 30000; // 30 seconds + private static final int DEFAULT_MAX_IP_MONITORING_TRIES = 30; // 30 tries private static final long DEFAULT_ACCOUNTING_UPDATE_PERIOD = 300000; // 5 minutes - + private final ManagerTimer requestSchedulerTimer; private final ManagerTimer tokenUpdaterTimer; private final ManagerTimer instanceMonitoringTimer; @@ -90,10 +104,12 @@ public class ManagerController { private Properties properties; private AsyncPacketSender packetSender; private FederationMemberValidator validator; + private ExecutorService benchmarkExecutor = Executors.newFixedThreadPool(10); + private Map asynchronousRequests = new ConcurrentHashMap(); - private ExecutorService benchmarkExecutor = Executors.newScheduledThreadPool(10); private DateUtils dateUtils = new DateUtils(); + public ManagerController(Properties properties) { this(properties, null); } @@ -149,6 +165,11 @@ public void setAccountingPlugin(AccountingPlugin accountingPlugin) { } } + private String getSSHCommonUser() { + String sshCommonUser = properties.getProperty(ConfigurationConstants.SSH_COMMON_USER); + return sshCommonUser == null ? DEFAULT_COMMON_SSH_USER : sshCommonUser; + } + private void triggerAccountingUpdater() { String accountingUpdaterPeriodStr = properties .getProperty(ConfigurationConstants.ACCOUNTING_UPDATE_PERIOD_KEY); @@ -215,8 +236,8 @@ protected void garbageCollector() { LOGGER.debug("Federation instances=" + federationInstances); for (Instance instance : federationInstances) { Request remoteRequest = requests.getRequestByInstance(instance.getId()); - if (!instanceHasRequestRelatedTo(null, generateGlobalId(instance.getId(), null)) - && remoteRequest != null && !remoteRequest.isLocal()) { + if ((!instanceHasRequestRelatedTo(null, generateGlobalId(instance.getId(), null)) + && remoteRequest != null && !remoteRequest.isLocal()) || remoteRequest == null) { // this is an orphan instance LOGGER.debug("Removing the orphan instance " + instance.getId()); this.computePlugin.removeInstance(federationUserToken, instance.getId()); @@ -378,7 +399,7 @@ public Instance getInstance(String accessId, String instanceId) { Request request = getRequestForInstance(accessId, instanceId); return getInstance(request); } - + private Instance getInstance(Request request) { Instance instance = null; if (isFulfilledByLocalMember(request)) { @@ -396,6 +417,7 @@ private Instance getInstance(Request request) { String sshPublicAdd = getSSHPublicAddress(request.getId()); if (sshPublicAdd != null) { instance.addAttribute(Instance.SSH_PUBLIC_ADDRESS_ATT, sshPublicAdd); + instance.addAttribute(Instance.SSH_USERNAME_ATT, getSSHCommonUser()); } Category osCategory = getImageCategory(request.getCategories()); if (osCategory != null) { @@ -432,8 +454,8 @@ private String getSSHPublicAddress(String tokenId) { } try { - String hostAddr = properties.getProperty(ConfigurationConstants.SSH_PRIVATE_HOST_KEY); - String httpHostPort = properties.getProperty(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY); + String hostAddr = properties.getProperty(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY); + String httpHostPort = properties.getProperty(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY); LOGGER.debug("private host: " + hostAddr); LOGGER.debug("private host HTTP port: " + httpHostPort); LOGGER.debug("tokenId: " + tokenId); @@ -446,7 +468,7 @@ private String getSSHPublicAddress(String tokenId) { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String sshPort = EntityUtils.toString(response.getEntity()); String sshPublicHostIP = properties - .getProperty(ConfigurationConstants.SSH_PUBLIC_HOST_KEY); + .getProperty(ConfigurationConstants.TUNNEL_SSH_PUBLIC_HOST_KEY); return sshPublicHostIP + ":" + sshPort; } } catch (Throwable e) { @@ -454,7 +476,7 @@ private String getSSHPublicAddress(String tokenId) { } return null; } - + private Instance getRemoteInstance(Request request) { return getRemoteInstance(request.getProvidingMemberId(), request.getInstanceId()); } @@ -594,12 +616,13 @@ public void queueServedRequest(String requestingMemberId, List categor public String createInstanceWithFederationUser(Request request) { FederationMember member = null; + boolean isRemoteDonation = !properties.getProperty("xmpp_jid").equals(request.getRequestingMemberId()); try { member = getFederationMember(request.getRequestingMemberId()); } catch (Exception e) { } - if (!properties.getProperty("xmpp_jid").equals(request.getRequestingMemberId()) && + if (isRemoteDonation && !validator.canDonateTo(member, request.getFederationToken())) { return null; } @@ -609,10 +632,7 @@ public String createInstanceWithFederationUser(Request request) { + xOCCIAtt + " for requesting member: " + request.getRequestingMemberId() + " with requestingToken " + request.getRequestingMemberId()); try { - String command = UserdataUtils.createBase64Command(request.getId(), - properties.getProperty(ConfigurationConstants.SSH_PRIVATE_HOST_KEY), - properties.getProperty(ConfigurationConstants.SSH_HOST_PORT_KEY), - properties.getProperty(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY)); + String command = createUserDataUtilsCommand(request); xOCCIAtt.put(RequestAttribute.USER_DATA_ATT.getValue(), command); categories.add(new Category(RequestConstants.USER_DATA_TERM, RequestConstants.SCHEME, RequestConstants.MIXIN_CLASS)); @@ -634,8 +654,10 @@ public String createInstanceWithFederationUser(Request request) { } try { + Map xOCCIAttCopy = new HashMap(xOCCIAtt); + removePublicKeyFromCategoriesAndAttributes(xOCCIAttCopy, categoriesWithoutImage); String instanceId = computePlugin.requestInstance(federationUserToken, categoriesWithoutImage, - xOCCIAtt, localImageId); + xOCCIAttCopy, localImageId); request.setState(RequestState.SPAWNING); execBenchmark(request, instanceId, properties.getProperty(ConfigurationConstants.XMPP_JID_KEY), true); @@ -644,7 +666,7 @@ public String createInstanceWithFederationUser(Request request) { if (e.getType() == ErrorType.QUOTA_EXCEEDED) { ArrayList requestsWithInstances = new ArrayList( requests.getRequestsIn(RequestState.FULFILLED, RequestState.DELETED)); - Request requestToPreemption = prioritizationPlugin.takeFrom(request.getRequestingMemberId(), requestsWithInstances); + Request requestToPreemption = prioritizationPlugin.takeFrom(request, requestsWithInstances); if (requestToPreemption == null) { throw e; @@ -660,6 +682,83 @@ public String createInstanceWithFederationUser(Request request) { } } + protected String createUserDataUtilsCommand(Request request) + throws IOException, MessagingException { + String command = UserdataUtils.createBase64Command(request.getId(), + properties.getProperty(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY), + properties.getProperty(ConfigurationConstants.TUNNEL_SSH_HOST_PORT_KEY), + properties.getProperty(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY), + getManagerSSHPublicKeyFilePath(), + request.getAttValue(RequestAttribute.DATA_PUBLIC_KEY.getValue()), + getSSHCommonUser()); + return command; + } + + protected String waitForSSHPublicAddress(Request request) { + int remainingTries = DEFAULT_MAX_IP_MONITORING_TRIES; + while (remainingTries-- > 0) { + Instance instance = getInstance(request); + String sshPublicAddress = instance.getAttributes().get(Instance.SSH_PUBLIC_ADDRESS_ATT); + if (sshPublicAddress != null) { + return sshPublicAddress; + } + try { + Thread.sleep(DEFAULT_INSTANCE_IP_MONITORING_PERIOD); + } catch (InterruptedException e) { + //do nothing + } + } + return null; + } + + private String getManagerSSHPublicKey() { + String publicSSHKeyFilePath = properties.getProperty(ConfigurationConstants.SSH_PUBLIC_KEY_PATH); + if (publicSSHKeyFilePath == null || publicSSHKeyFilePath.isEmpty()) { + return null; + } + File managerPublicKeyFile = new File(publicSSHKeyFilePath); + if (!managerPublicKeyFile.exists()) { + return null; + } + try { + return IOUtils.toString(new FileInputStream(managerPublicKeyFile)); + } catch (IOException e) { + LOGGER.warn("Could not read manager public key file", e); + return null; + } + } + + private String getManagerSSHPublicKeyFilePath() { + String publicKeyFilePath = properties.getProperty(ConfigurationConstants.SSH_PUBLIC_KEY_PATH); + if (publicKeyFilePath == null || publicKeyFilePath.isEmpty()) { + return null; + } + return publicKeyFilePath; + } + + private String getManagerSSHPrivateKeyFilePath() { + String publicKeyFilePath = properties.getProperty(ConfigurationConstants.SSH_PRIVATE_KEY_PATH); + if (publicKeyFilePath == null || publicKeyFilePath.isEmpty()) { + return null; + } + return publicKeyFilePath; + } + + private void removePublicKeyFromCategoriesAndAttributes(Map xOCCIAtt, + List categories) { + xOCCIAtt.remove(RequestAttribute.DATA_PUBLIC_KEY.getValue()); + Category toRemove = null; + for (Category category : categories) { + if (category.getTerm().equals(RequestConstants.PUBLIC_KEY_TERM)) { + toRemove = category; + break; + } + } + if (toRemove != null) { + categories.remove(toRemove); + } + } + protected void preemption(Request requestToPreemption) { removeInstance(requestToPreemption.getInstanceId(), requestToPreemption); } @@ -893,13 +992,17 @@ private void createAsynchronousRemoteInstance(final Request request, List xOCCIAttCopy = new HashMap(request.getxOCCIAtt()); + List categoriesCopy = new LinkedList(request.getCategories()); + removePublicKeyFromCategoriesAndAttributes(xOCCIAttCopy, categoriesCopy); request.setProvidingMemberId(memberAddress); LOGGER.info("Submiting request " + request + " to member " + memberAddress); asynchronousRequests.put(request.getId(), new ForwardedRequest(request, dateUtils.currentTimeMillis())); - ManagerPacketHelper.asynchronousRemoteRequest(request, memberAddress, + ManagerPacketHelper.asynchronousRemoteRequest(request.getId(), categoriesCopy, xOCCIAttCopy, memberAddress, federationIdentityPlugin.getForwardableToken(request.getFederationToken()), packetSender, new AsynchronousRequestCallback() { @@ -958,10 +1061,7 @@ private boolean createLocalInstance(Request request) { try { try { - String command = UserdataUtils.createBase64Command(request.getId(), - properties.getProperty(ConfigurationConstants.SSH_PRIVATE_HOST_KEY), - properties.getProperty(ConfigurationConstants.SSH_HOST_PORT_KEY), - properties.getProperty(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY)); + String command = createUserDataUtilsCommand(request); request.putAttValue(RequestAttribute.USER_DATA_ATT.getValue(), command); request.addCategory(new Category(RequestConstants.USER_DATA_TERM, RequestConstants.SCHEME, RequestConstants.MIXIN_CLASS)); @@ -980,9 +1080,12 @@ private boolean createLocalInstance(Request request) { continue; } categories.add(category); - } + } + + Map xOCCIAttCopy = new HashMap(request.getxOCCIAtt()); + removePublicKeyFromCategoriesAndAttributes(xOCCIAttCopy, categories); String instanceId = computePlugin.requestInstance(request.getLocalToken(), - categories, request.getxOCCIAtt(), localImageId); + categories, xOCCIAttCopy, localImageId); request.setState(RequestState.SPAWNING); execBenchmark(request, instanceId, properties.getProperty(ConfigurationConstants.XMPP_JID_KEY), false); @@ -1022,19 +1125,29 @@ private void execBenchmark(final Request request, final String instanceId, benchmarkExecutor.execute(new Runnable() { @Override public void run() { - Instance instance = null; - if (fulfilledByFederationUser) { - instance = computePlugin.getInstance(getFederationUserToken(), instanceId); - } else { - instance = computePlugin.getInstance(request.getLocalToken(), instanceId); + Request tempRequest = new Request(request); + tempRequest.setInstanceId(instanceId); + tempRequest.setState(RequestState.FULFILLED); + tempRequest.setProvidingMemberId(providingMemberAddress); + tempRequest.setFulfilledByFederationUser(fulfilledByFederationUser); + + String sshPublicAddress = null; + if (getManagerSSHPublicKey() != null) { + sshPublicAddress = waitForSSHPublicAddress(tempRequest); + waitForSSHConnectivity(sshPublicAddress); } + benchmarkingPlugin.run(generateGlobalId(instanceId, providingMemberAddress), - instance); + getInstance(tempRequest)); + + if (sshPublicAddress != null) { + replacePublicKeys(sshPublicAddress, request); + } - request.setInstanceId(instanceId); - request.setState(RequestState.FULFILLED); - request.setProvidingMemberId(providingMemberAddress); - request.setFulfilledByFederationUser(fulfilledByFederationUser); + request.setInstanceId(tempRequest.getInstanceId()); + request.setState(tempRequest.getState()); + request.setProvidingMemberId(tempRequest.getProvidingMemberId()); + request.setFulfilledByFederationUser(tempRequest.isFulfilledByFederationUser()); if (request.isLocal() && !isFulfilledByLocalMember(request)) { asynchronousRequests.remove(request.getId()); @@ -1055,7 +1168,61 @@ public void run() { } } }); + } + + protected void replacePublicKeys(String sshPublicAddress, Request request) { + String requestPublicKey = request.getAttValue(RequestAttribute.DATA_PUBLIC_KEY.getValue()); + if (requestPublicKey == null) { + requestPublicKey = ""; + } + String sshCmd = "echo \"" + requestPublicKey + "\" > ~/.ssh/authorized_keys"; + try { + Command sshOutput = execOnInstance(sshPublicAddress, sshCmd); + if (sshOutput.getExitStatus() != 0) { + LOGGER.error("Could not replace SSH public key. Exit value = " + sshOutput.getExitStatus()); + } + } catch (Exception e) { + LOGGER.error("Could not replace SSH public key.", e); + } + } + + private void waitForSSHConnectivity(String sshPublicAddress) { + if (sshPublicAddress == null) { + return; + } + int retries = DEFAULT_MAX_IP_MONITORING_TRIES; + while (retries-- > 0) { + try { + Command sshOutput = execOnInstance(sshPublicAddress, "echo HelloWorld"); + if (sshOutput.getExitStatus() == 0) { + break; + } + Thread.sleep(DEFAULT_INSTANCE_IP_MONITORING_PERIOD); + } catch (Exception e) { + LOGGER.debug("Could not connect to instance to run benchmarking", e); + } + } + } + + private Command execOnInstance(String sshPublicAddress, String cmd) throws Exception { + SshHelper sshHelper = createSshHelper(); + String[] sshAddressAndPort = sshPublicAddress.split(":"); + try { + sshHelper.connect(sshAddressAndPort[0], Integer.parseInt(sshAddressAndPort[1]), + getSSHCommonUser(), getManagerSSHPrivateKeyFilePath()); + Command sshOutput = sshHelper.doSshExecution(cmd); + return sshOutput; + } finally { + try { + sshHelper.disconnect(); + } catch (IOException e) { + LOGGER.warn("Could not disconnect ssh client.", e); + } + } + } + protected SshHelper createSshHelper() { + return new SshHelper(); } private void triggerRequestScheduler() { @@ -1197,7 +1364,6 @@ private boolean createLocalInstanceWithFederationUser(Request request) { try { instanceId = createInstanceWithFederationUser(request); } catch (Exception e) { - e.printStackTrace(); LOGGER.info("Could not create instance with federation user locally. " + e); } diff --git a/src/main/java/org/fogbowcloud/manager/core/RoundRobinMemberPicker.java b/src/main/java/org/fogbowcloud/manager/core/RoundRobinMemberPicker.java index c84fc3a2..aaadc933 100644 --- a/src/main/java/org/fogbowcloud/manager/core/RoundRobinMemberPicker.java +++ b/src/main/java/org/fogbowcloud/manager/core/RoundRobinMemberPicker.java @@ -34,7 +34,7 @@ public FederationMember pick(List members) { } if (!containsInList) { membersListCopy.add(new FederationMember(new ResourcesInfo(lastMember, "", "", "", - "", null))); + "", "", ""))); } } diff --git a/src/main/java/org/fogbowcloud/manager/core/UserdataUtils.java b/src/main/java/org/fogbowcloud/manager/core/UserdataUtils.java index 9fb28fc0..2e2f184f 100644 --- a/src/main/java/org/fogbowcloud/manager/core/UserdataUtils.java +++ b/src/main/java/org/fogbowcloud/manager/core/UserdataUtils.java @@ -1,12 +1,21 @@ package org.fogbowcloud.manager.core; +import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.internet.MimeBodyPart; import org.apache.commons.codec.Charsets; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; +import org.fogbowcloud.manager.core.plugins.util.CloudInitUserDataBuilder; public class UserdataUtils { @@ -14,24 +23,68 @@ public class UserdataUtils { protected static final String TOKEN_HOST_STR = "#TOKEN_HOST#"; protected static final String TOKEN_HOST_HTTP_PORT_STR = "#TOKEN_HOST_HTTP_PORT#"; protected static final String TOKEN_HOST_SSH_PORT_STR = "#TOKEN_HOST_SSH_PORT#"; + protected static final String TOKEN_MANAGER_SSH_PUBLIC_KEY = "#TOKEN_MANAGER_SSH_PUBLIC_KEY#"; + protected static final String TOKEN_MANAGER_SSH_USER = "#TOKEN_MANAGER_SSH_USER#"; + private static final String DEFAULT_SSH_HOST_PORT = "22"; public static String createBase64Command(String tokenId, String sshPrivateHostIP, - String sshRemoteHostPort, String sshRemoteHostHttpPort) throws FileNotFoundException, IOException { + String sshRemoteHostPort, String sshRemoteHostHttpPort, String managerPublicKeyFilePath, + String userPublicKey, String sshCommonUser) + throws IOException, MessagingException { - String sshTunnelCmd = IOUtils.toString(new FileInputStream( - "bin/fogbow-create-reverse-tunnel")); + String sshTunnelCmdFilePath = "bin/fogbow-create-reverse-tunnel"; + String cloudConfigFilePath = "bin/fogbow-cloud-config.cfg"; if (sshRemoteHostPort == null || sshRemoteHostPort.isEmpty()) { sshRemoteHostPort = DEFAULT_SSH_HOST_PORT; } - sshTunnelCmd = sshTunnelCmd.replace(TOKEN_ID_STR, tokenId); - sshTunnelCmd = sshTunnelCmd.replace(TOKEN_HOST_STR, sshPrivateHostIP); - sshTunnelCmd = sshTunnelCmd.replace(TOKEN_HOST_SSH_PORT_STR, sshRemoteHostPort); - sshTunnelCmd = sshTunnelCmd.replace(TOKEN_HOST_HTTP_PORT_STR, sshRemoteHostHttpPort); - - return new String(Base64.encodeBase64(sshTunnelCmd.getBytes(Charsets.UTF_8), false, false), + + CloudInitUserDataBuilder cloudInitUserDataBuilder = CloudInitUserDataBuilder.start(); + cloudInitUserDataBuilder.addShellScript(new FileReader(sshTunnelCmdFilePath)); + + if (managerPublicKeyFilePath != null || userPublicKey != null) { + cloudInitUserDataBuilder.addCloudConfig(new FileReader(new File(cloudConfigFilePath))); + } + + String mimeString = cloudInitUserDataBuilder.buildUserData(); + + Map replacements = new HashMap(); + replacements.put(TOKEN_ID_STR, tokenId); + replacements.put(TOKEN_HOST_STR, sshPrivateHostIP); + replacements.put(TOKEN_HOST_SSH_PORT_STR, sshRemoteHostPort); + replacements.put(TOKEN_HOST_HTTP_PORT_STR, sshRemoteHostHttpPort); + + String publicKeyToBeReplaced = null; + if (managerPublicKeyFilePath != null) { + publicKeyToBeReplaced = IOUtils.toString(new FileInputStream( + new File(managerPublicKeyFilePath))); + } else if (userPublicKey != null) { + publicKeyToBeReplaced = userPublicKey; + } + if (publicKeyToBeReplaced != null) { + replacements.put(TOKEN_MANAGER_SSH_PUBLIC_KEY, publicKeyToBeReplaced); + replacements.put(TOKEN_MANAGER_SSH_USER, sshCommonUser); + } + + for (Entry entry : replacements.entrySet()) { + mimeString = mimeString.replace(entry.getKey(), entry.getValue()); + } + + return new String(Base64.encodeBase64(mimeString.getBytes(Charsets.UTF_8), false, false), Charsets.UTF_8); } - + + public static void addMimeBodyPart(Multipart mimeMultipart, String filePath, String fileFormatType) + throws IOException, MessagingException { + + File file = new File(filePath); + String fileContent = IOUtils.toString(new FileInputStream(file)); + MimeBodyPart subMessage = new MimeBodyPart(); + subMessage.setText(fileContent); + subMessage.setContent(fileContent, fileFormatType); + subMessage.addHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); + mimeMultipart.addBodyPart(subMessage); + } + } diff --git a/src/main/java/org/fogbowcloud/manager/core/model/ResourcesInfo.java b/src/main/java/org/fogbowcloud/manager/core/model/ResourcesInfo.java index b1f08db1..81b27bcd 100644 --- a/src/main/java/org/fogbowcloud/manager/core/model/ResourcesInfo.java +++ b/src/main/java/org/fogbowcloud/manager/core/model/ResourcesInfo.java @@ -1,6 +1,5 @@ package org.fogbowcloud.manager.core.model; -import java.util.List; public class ResourcesInfo { @@ -9,21 +8,26 @@ public class ResourcesInfo { private String cpuInUse; private String memIdle; private String memInUse; - private List flavors; + private String instancesIdle; + private String instancesInUse; public ResourcesInfo(String id, String cpuIdle, String cpuInUse, - String memIdle, String memInUse, List flavours) { + String memIdle, String memInUse, + String instancesIdle, String instancesInUse) { setId(id); setCpuIdle(cpuIdle); setCpuInUse(cpuInUse); setMemIdle(memIdle); setMemInUse(memInUse); - setFlavours(flavours); + setInstancesIdle(instancesIdle); + setInstancesInUse(instancesInUse); } public ResourcesInfo(String cpuIdle, String cpuInUse, - String memIdle, String memInUse, List flavours) { - this(null, cpuIdle, cpuInUse, memIdle, memInUse, flavours); + String memIdle, String memInUse, + String instancesIdle, String instancesInUse) { + this(null, cpuIdle, cpuInUse, memIdle, memInUse, + instancesIdle, instancesInUse); } public String getId() { @@ -81,12 +85,20 @@ public void setMemInUse(String memInUse) { } this.memInUse = memInUse; } - - public List getFlavors() { - return flavors; + + public void setInstancesIdle(String instancesIdle) { + this.instancesIdle = instancesIdle; } - - public void setFlavours(List flavors) { - this.flavors = flavors; + + public String getInstancesIdle() { + return instancesIdle; + } + + public void setInstancesInUse(String instancesInUse) { + this.instancesInUse = instancesInUse; + } + + public String getInstancesInUse() { + return instancesInUse; } } diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/PrioritizationPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/PrioritizationPlugin.java index 8dd0115c..11380a06 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/PrioritizationPlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/PrioritizationPlugin.java @@ -6,6 +6,6 @@ public interface PrioritizationPlugin { - public Request takeFrom(String requestingMemberId, List requestsWithInstance); + public Request takeFrom(Request newRequest, List requestsWithInstance); } diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/SSHBenchmarkingPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/SSHBenchmarkingPlugin.java new file mode 100644 index 00000000..0f75d06c --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/SSHBenchmarkingPlugin.java @@ -0,0 +1,119 @@ +package org.fogbowcloud.manager.core.plugins.benchmarking; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import net.schmizz.sshj.connection.channel.direct.Session.Command; + +import org.apache.log4j.Logger; +import org.fogbowcloud.manager.core.ConfigurationConstants; +import org.fogbowcloud.manager.core.ManagerController; +import org.fogbowcloud.manager.core.plugins.BenchmarkingPlugin; +import org.fogbowcloud.manager.core.plugins.util.SshHelper; +import org.fogbowcloud.manager.occi.instance.Instance; + +public class SSHBenchmarkingPlugin implements BenchmarkingPlugin { + + Map instanceToPower = new HashMap(); + + private static final Logger LOGGER = Logger.getLogger(SSHBenchmarkingPlugin.class); + private static final String SSH_BENCHMARKING_SCRIPT_URL = "ssh_benchmarking_script_url"; + + private static final String STAGE_COMMAND = "curl %s -o exec;chmod +x exec;"; + private static final String EXEC_COMMAND = "./exec"; + + private String scriptUrl; + private String managerPrivateKeyFilePath; + private String sshCommonUser; + + public SSHBenchmarkingPlugin(Properties properties) { + this.scriptUrl = properties.getProperty( + SSH_BENCHMARKING_SCRIPT_URL); + this.managerPrivateKeyFilePath = properties.getProperty( + ConfigurationConstants.SSH_PRIVATE_KEY_PATH); + this.sshCommonUser = getSSHCommonUser(properties); + } + + private static String getSSHCommonUser(Properties properties) { + String sshCommonUser = properties.getProperty(ConfigurationConstants.SSH_COMMON_USER); + return sshCommonUser == null ? sshCommonUser : ManagerController.DEFAULT_COMMON_SSH_USER; + } + + @Override + public void run(String globalInstanceId, Instance instance) { + if (instance == null) { + throw new IllegalArgumentException("Instance must not be null."); + } + LOGGER.info("Running benchmarking on instance: " + globalInstanceId); + + double power = UNDEFINED_POWER; + String ipAndPort = instance.getAttributes().get(Instance.SSH_PUBLIC_ADDRESS_ATT); + if (ipAndPort != null) { + + long benchmarkingTime = sshBenchmarking(ipAndPort, sshCommonUser); + if (benchmarkingTime > 0) { + power = getFCUsFromOutput(benchmarkingTime); + } + } + + LOGGER.debug("Putting instanceId " + globalInstanceId + " and power " + power); + instanceToPower.put(globalInstanceId, power); + } + + private long sshBenchmarking(String ipAndPort, String user) { + SshHelper ssh = new SshHelper(); + long millis = 0; + try { + String[] sshAddressData = ipAndPort.split(":"); + ssh.connect(sshAddressData[0], Integer.parseInt(sshAddressData[1]), user, + this.managerPrivateKeyFilePath); + Command stagingCmd = ssh.doSshExecution(String.format(STAGE_COMMAND, scriptUrl)); + if (stagingCmd.getExitStatus() == 0) { + long startTimestamp = System.currentTimeMillis(); + Command executeBenchcmd = ssh.doSshExecution(EXEC_COMMAND); + long endTimestamp = System.currentTimeMillis(); + if (executeBenchcmd.getExitStatus() == 0) { + return endTimestamp - startTimestamp; + } + } + } catch (Exception e) { + LOGGER.warn("Couldn't run benchmark.", e); + } + return millis; + } + + /** + * TESTED! + * + * Converts the time that the bench run into FCUs. + * + * @param output + * The output from benchmark in ssh. + * @return The amount of FCUs benchmarked. + */ + protected double getFCUsFromOutput(long milliseconds) { + System.out.println(milliseconds + " milliseconds"); + + double seconds = (double) TimeUnit.MILLISECONDS.toSeconds(milliseconds); + return (10.0 / seconds); + + } + + @Override + public double getPower(String globalInstanceId) { + LOGGER.debug("Getting power of instance " + globalInstanceId); + LOGGER.debug("Current instanceToPower=" + instanceToPower); + if (instanceToPower.get(globalInstanceId) == null) { + return UNDEFINED_POWER; + } + return instanceToPower.get(globalInstanceId); + } + + @Override + public void remove(String globalInstanceId) { + LOGGER.debug("Removing instance: " + globalInstanceId + " from benchmarking map."); + instanceToPower.remove(globalInstanceId); + } +} diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/FCUStaticBenchmarkingPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/VanillaBenchmarkingPlugin.java similarity index 89% rename from src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/FCUStaticBenchmarkingPlugin.java rename to src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/VanillaBenchmarkingPlugin.java index 14a8608f..26491832 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/FCUStaticBenchmarkingPlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/benchmarking/VanillaBenchmarkingPlugin.java @@ -8,13 +8,13 @@ import org.fogbowcloud.manager.core.plugins.BenchmarkingPlugin; import org.fogbowcloud.manager.occi.instance.Instance; -public class FCUStaticBenchmarkingPlugin implements BenchmarkingPlugin { +public class VanillaBenchmarkingPlugin implements BenchmarkingPlugin { Map instanceToPower = new HashMap(); - private static final Logger LOGGER = Logger.getLogger(FCUStaticBenchmarkingPlugin.class); + private static final Logger LOGGER = Logger.getLogger(VanillaBenchmarkingPlugin.class); - public FCUStaticBenchmarkingPlugin(Properties properties) { + public VanillaBenchmarkingPlugin(Properties properties) { } @Override diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/compute/NoCloudComputePlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/compute/NoCloudComputePlugin.java new file mode 100644 index 00000000..88ffe2a8 --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/compute/NoCloudComputePlugin.java @@ -0,0 +1,79 @@ +package org.fogbowcloud.manager.core.plugins.compute; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.fogbowcloud.manager.core.model.ImageState; +import org.fogbowcloud.manager.core.model.ResourcesInfo; +import org.fogbowcloud.manager.core.plugins.ComputePlugin; +import org.fogbowcloud.manager.occi.core.Category; +import org.fogbowcloud.manager.occi.core.ErrorType; +import org.fogbowcloud.manager.occi.core.OCCIException; +import org.fogbowcloud.manager.occi.core.Token; +import org.fogbowcloud.manager.occi.instance.Instance; +import org.restlet.Request; +import org.restlet.Response; + +public class NoCloudComputePlugin implements ComputePlugin { + + private static final String ZERO = Integer.toString(0); + private static final String FAKE_IMAGE_ID = "no-image"; + + public NoCloudComputePlugin(Properties properties) {} + + @Override + public String requestInstance(Token token, List categories, + Map xOCCIAtt, String imageId) { + throw new OCCIException(ErrorType.QUOTA_EXCEEDED, "There is no underlying cloud."); + } + + @Override + public List getInstances(Token token) { + return new ArrayList(); + } + + @Override + public Instance getInstance(Token token, String instanceId) { + return null; + } + + @Override + public void removeInstance(Token token, String instanceId) { + + } + + @Override + public void removeInstances(Token token) { + + } + + @Override + public ResourcesInfo getResourcesInfo(Token token) { + return new ResourcesInfo(ZERO, ZERO, ZERO, + ZERO, ZERO, ZERO); + } + + @Override + public void bypass(Request request, Response response) { + + } + + @Override + public void uploadImage(Token token, String imagePath, String imageName, + String diskFormat) { + + } + + @Override + public String getImageId(Token token, String imageName) { + return FAKE_IMAGE_ID; + } + + @Override + public ImageState getImageState(Token token, String imageName) { + return ImageState.ACTIVE; + } + +} diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/ShellWrapper.java b/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/ShellWrapper.java new file mode 100644 index 00000000..c05a70f4 --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/ShellWrapper.java @@ -0,0 +1,27 @@ +package org.fogbowcloud.manager.core.plugins.imagestorage.vmcatcher; + +import java.io.IOException; +import java.util.Arrays; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; + +public class ShellWrapper { + + private static final Logger LOGGER = Logger.getLogger(ShellWrapper.class); + + public void execute(String... command) throws IOException, + InterruptedException { + ProcessBuilder builder = new ProcessBuilder(command); + Process process = builder.start(); + + int exitValue = process.waitFor(); + String stdout = IOUtils.toString(process.getInputStream()); + String stderr = IOUtils.toString(process.getErrorStream()); + + LOGGER.debug("Command " + Arrays.asList(command) + " has finished. " + + "Exit: " + exitValue + "; Stdout: " + stdout + "; Stderr: " + + stderr); + } + +} diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/VMCatcherStoragePlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/VMCatcherStoragePlugin.java index 92021fad..84953309 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/VMCatcherStoragePlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/VMCatcherStoragePlugin.java @@ -5,15 +5,14 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.util.Arrays; import java.util.Properties; -import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.mail.MessagingException; import javax.mail.Session; +import javax.mail.internet.ContentType; import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; @@ -32,18 +31,27 @@ public class VMCatcherStoragePlugin extends StaticImageStoragePlugin { private static final Logger LOGGER = Logger.getLogger(ImageStoragePlugin.class); - private static final Executor IMAGE_DOWNLOADER = Executors.newFixedThreadPool(5); - private static final String PROP_VMC_MAPPING_FILE = "image_storage_vmcatcher_glancepush_vmcmapping_file"; - private static final String PROP_VMC_PUSH_METHOD = "image_storage_vmcatcher_push_method"; + protected static final String PROP_VMC_MAPPING_FILE = "image_storage_vmcatcher_glancepush_vmcmapping_file"; + protected static final String PROP_VMC_PUSH_METHOD = "image_storage_vmcatcher_push_method"; private Properties props; private ComputePlugin computePlugin; + private ExecutorService imageDownloader; + private ShellWrapper shellWrapper; - public VMCatcherStoragePlugin(Properties properties, ComputePlugin computePlugin) { + protected VMCatcherStoragePlugin(Properties properties, ComputePlugin computePlugin, + ExecutorService imageDownloader, ShellWrapper shellWrapper) { super(properties, computePlugin); this.props = properties; this.computePlugin = computePlugin; + this.imageDownloader = imageDownloader; + this.shellWrapper = shellWrapper; + } + + public VMCatcherStoragePlugin(Properties properties, ComputePlugin computePlugin) { + this(properties, computePlugin, Executors.newFixedThreadPool(5), + new ShellWrapper()); } @Override @@ -67,9 +75,11 @@ public String getLocalId(Token token, String globalId) { } else if (pushMethod.equals("cesga")) { imageTitleTranslated = getImageNameWithCESGAPush(imageInfo); } + if (imageTitleTranslated == null) { + return null; + } - localId = imageTitleTranslated == null ? null : computePlugin - .getImageId(token, imageTitleTranslated); + localId = computePlugin.getImageId(token, imageTitleTranslated); if (localId != null) { return localId; } @@ -81,7 +91,7 @@ public String getLocalId(Token token, String globalId) { LOGGER.warn("Couldn't add image.list to VMCatcher subscription list", e); } - IMAGE_DOWNLOADER.execute(new Runnable() { + imageDownloader.execute(new Runnable() { @Override public void run() { try { @@ -98,24 +108,27 @@ public void run() { private void executeShellCommand(String... command) throws IOException, InterruptedException { - ProcessBuilder builder = new ProcessBuilder(command); - Process process = builder.start(); - - int exitValue = process.waitFor(); - String stdout = IOUtils.toString(process.getInputStream()); - String stderr = IOUtils.toString(process.getErrorStream()); - - LOGGER.debug("Command " + Arrays.asList(command) + " has finished. " - + "Exit: " + exitValue + "; Stdout: " + stdout + "; Stderr: " + stderr); + shellWrapper.execute(command); } private String getImageNameWithCESGAPush(JSONObject imageInfo) { - return imageInfo.optJSONObject("hv:imagelist").optString("dc:identifier"); + JSONObject imageListJson = imageInfo.optJSONObject("hv:imagelist"); + if (imageListJson == null) { + return null; + } + return imageListJson.optString("dc:identifier", null); } private String getImageNameWithGlancePush(JSONObject imageInfo) { String imageTitleTranslated = null; - String imageTitle = imageInfo.optJSONObject("hv:imagelist").optString("dc:title"); + JSONObject imageListJson = imageInfo.optJSONObject("hv:imagelist"); + if (imageListJson == null) { + return null; + } + String imageTitle = imageListJson.optString("dc:title", null); + if (imageTitle == null) { + return null; + } if (this.props.containsKey(PROP_VMC_MAPPING_FILE)) { try { JSONObject vmcMapping = new JSONObject(IOUtils.toString( @@ -139,9 +152,11 @@ private JSONObject retrieveImageListInfo(String globalId) InputStream imageListStream = imageListURL.openStream(); MimeMessage message = new MimeMessage( Session.getDefaultInstance(new Properties()), imageListStream); - MimeMultipart mime = (MimeMultipart) message.getContent(); - JSONObject imageInfo = new JSONObject(IOUtils.toString( - mime.getBodyPart(0).getInputStream())); + ContentType type = new ContentType(message.getHeader("Content-Type")[0]); + String boundary = type.getParameter("boundary"); + String messageContent = IOUtils.toString(message.getInputStream()); + String[] splitMessageContent = messageContent.split("--" + boundary); + JSONObject imageInfo = new JSONObject(splitMessageContent[1]); imageListStream.close(); return imageInfo; diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/opennebula/OpenNebulaComputePlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/opennebula/OpenNebulaComputePlugin.java index 73b51e65..8e6f2629 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/opennebula/OpenNebulaComputePlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/opennebula/OpenNebulaComputePlugin.java @@ -414,14 +414,15 @@ public ResourcesInfo getResourcesInfo(Token token) { resourceQuota = getQuota(maxUserVMsStr, vmsUserInUseStr, maxGroupVMsStr, vmsGroupInUseStr); double maxVMs = resourceQuota.getMax(); - double vmsInUse = resourceQuota.getInUse(); + int instancesInUse = (int) resourceQuota.getInUse(); double cpuIdle = maxCpu - cpuInUse; double memIdle = maxMem - memInUse; - double instancesIdle = maxVMs - vmsInUse; + int instancesIdle = (int) (maxVMs - instancesInUse); return new ResourcesInfo(String.valueOf(cpuIdle), String.valueOf(cpuInUse), - String.valueOf(memIdle), String.valueOf(memInUse), getFlavors(cpuIdle, memIdle, instancesIdle)); + String.valueOf(memIdle), String.valueOf(memInUse), + String.valueOf(instancesIdle), String.valueOf(instancesInUse)); } private ResourceQuota getQuota(String maxUserResource, String resourceUserInUse, String maxGroupResource, String resourceGroupInUse) { @@ -479,28 +480,6 @@ private boolean isValidNumber(String number) { return true; } - private List getFlavors(double cpuIdle, double memIdle, double instancesIdle) { - - List newFlavorsList = new ArrayList(); - for (Flavor flavor : this.flavors) { - int capacity = 0; - try { - double memFlavor = Double.parseDouble(flavor.getMem()); - double cpuFlavor = Double.parseDouble(flavor.getCpu()); - capacity = Math.min((int) Math.min(cpuIdle / cpuFlavor, memIdle / memFlavor), - (int) instancesIdle); - } catch (Exception e) { - LOGGER.error("", e); - throw new OCCIException(ErrorType.BAD_REQUEST, - ResponseConstants.INVALID_FLAVOR_SPECIFIED); - } - flavor.setCapacity(capacity); - newFlavorsList.add(flavor); - } - - return newFlavorsList; - } - @Override public void bypass(Request request, Response response) { response.setStatus(new Status(HttpStatus.SC_BAD_REQUEST), diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackConfigurationConstants.java b/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackConfigurationConstants.java index 42cde3d2..12c132dd 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackConfigurationConstants.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackConfigurationConstants.java @@ -54,6 +54,6 @@ public class OpenStackConfigurationConstants { public static final String MAX_TOTAL_RAM_SIZE_ATT = "maxTotalRAMSize"; public static final String TOTAL_RAM_USED_ATT = "totalRAMUsed"; public static final String MAX_TOTAL_INSTANCES_ATT = "maxTotalInstances"; - public static final String TOTAL_INSTANCES_USED_ATT = "totalInstancesUsed"; + public static final String TOTAL_INSTANCES_USED_ATT = "totalInstancesUsed"; } diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackNovaV2ComputePlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackNovaV2ComputePlugin.java index 45f23444..d7e506c5 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackNovaV2ComputePlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/openstack/OpenStackNovaV2ComputePlugin.java @@ -487,7 +487,7 @@ public ResourcesInfo getResourcesInfo(Token token) { int instancesIdle = Integer.parseInt(maxInstances) - Integer.parseInt(instancesInUse); return new ResourcesInfo(String.valueOf(cpuIdle), cpuInUse, String.valueOf(memIdle), - memInUse, getFlavors(cpuIdle, memIdle, instancesIdle)); + memInUse, String.valueOf(instancesIdle), instancesInUse); } private String getAttFromLimitsJson(String attName, String responseStr) { @@ -500,24 +500,6 @@ private String getAttFromLimitsJson(String attName, String responseStr) { } } - private List getFlavors(int cpuIdle, int memIdle, int instancesIdle) { - List flavors = new ArrayList(); - - // flavors - int capacitySmall = Math.min(instancesIdle, Math.min(cpuIdle / 1, memIdle / 128)); - Flavor smallFlavor = new Flavor(RequestConstants.SMALL_TERM, "1", "128", capacitySmall); - int capacityMedium = Math.min(instancesIdle, Math.min(cpuIdle / 2, memIdle / 512)); - Flavor mediumFlavor = new Flavor(RequestConstants.MEDIUM_TERM, "2", "512", capacityMedium); - int capacityLarge = Math.min(instancesIdle, Math.min(cpuIdle / 4, memIdle / 1024)); - Flavor largeFlavor = new Flavor(RequestConstants.LARGE_TERM, "4", "1024", capacityLarge); - - flavors.add(smallFlavor); - flavors.add(mediumFlavor); - flavors.add(largeFlavor); - - return flavors; - } - @Override public void bypass(Request request, Response response) { response.setStatus(new Status(HttpStatus.SC_BAD_REQUEST), diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/FCFSPrioritizationPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/FCFSPrioritizationPlugin.java index f5aa402c..4017e1ba 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/FCFSPrioritizationPlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/FCFSPrioritizationPlugin.java @@ -13,7 +13,7 @@ public FCFSPrioritizationPlugin(Properties properties, AccountingPlugin accounti } @Override - public Request takeFrom(String requestingMemberId, List requestsWithInstance) { + public Request takeFrom(Request newRequest, List requestsWithInstance) { return null; } } diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/PriotizeRemoteRequestPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/PriotizeRemoteRequestPlugin.java new file mode 100644 index 00000000..34327876 --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/PriotizeRemoteRequestPlugin.java @@ -0,0 +1,58 @@ +package org.fogbowcloud.manager.core.plugins.prioritization; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.fogbowcloud.manager.core.plugins.AccountingPlugin; +import org.fogbowcloud.manager.core.plugins.PrioritizationPlugin; +import org.fogbowcloud.manager.occi.request.Request; + +public class PriotizeRemoteRequestPlugin implements PrioritizationPlugin { + + private static final Logger LOGGER = Logger.getLogger(PriotizeRemoteRequestPlugin.class); + + public PriotizeRemoteRequestPlugin(Properties properties, AccountingPlugin accountingPlugin){ + + } + + @Override + public Request takeFrom(Request newRequest, List requestsWithInstance) { + LOGGER.debug("Choosing request to take instance from requestsWithInstance=" + + requestsWithInstance + " for requestMember=" + newRequest.getRequestingMemberId()); + + if (newRequest.isLocal()) { + return null; + } + + List federationUserRequests = filterRequestsFulfilledByFedUser(requestsWithInstance); + LOGGER.debug("federationUserRequests=" + federationUserRequests); + return getMostRecentRequest(federationUserRequests); + } + + private List filterRequestsFulfilledByFedUser(List requestsWithInstance) { + List federationUserRequests = new ArrayList(); + for (Request currentRequest : requestsWithInstance) { + if (currentRequest.isFulfilledByFederationUser()) { + federationUserRequests.add(currentRequest); + } + } + return federationUserRequests; + } + + private Request getMostRecentRequest(List requests) { + if (requests.isEmpty()) { + return null; + } + Request mostRecentRequest = requests.get(0); + for (Request currentRequest : requests) { + if (new Date(mostRecentRequest.getFulfilledTime()).compareTo(new Date(currentRequest + .getFulfilledTime())) < 0) { + mostRecentRequest = currentRequest; + } + } + return mostRecentRequest; + } +} diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/TwoFoldPrioritizationPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/TwoFoldPrioritizationPlugin.java index bd399d36..2b38d7d8 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/TwoFoldPrioritizationPlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/TwoFoldPrioritizationPlugin.java @@ -1,5 +1,6 @@ package org.fogbowcloud.manager.core.plugins.prioritization; +import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -43,9 +44,18 @@ private static Object createInstanceWithAccoutingPlugin( } @Override - public Request takeFrom(String requestingMemberId, List requestsWithInstance) { - Request localPreemption = localPrioritizationPlugin.takeFrom(requestingMemberId, requestsWithInstance); + public Request takeFrom(Request newRequest, List requestsWithInstance) { + List localRequests = new ArrayList(); + List servedRequests = new ArrayList(); + for (Request currentRequest : requestsWithInstance) { + if (currentRequest.isLocal()) { + localRequests.add(currentRequest); + } else { + servedRequests.add(currentRequest); + } + } + Request localPreemption = localPrioritizationPlugin.takeFrom(newRequest, localRequests); return (localPreemption != null) ? localPreemption : - remotePrioritizationPlugin.takeFrom(requestingMemberId, requestsWithInstance); + remotePrioritizationPlugin.takeFrom(newRequest, servedRequests); } } diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/FederationMemberDebt.java b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/FederationMemberDebt.java index 46bdc53a..62b8631a 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/FederationMemberDebt.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/FederationMemberDebt.java @@ -9,7 +9,7 @@ public class FederationMemberDebt { private double debt; public FederationMemberDebt(String memberId, double debt) { - this(new FederationMember(new ResourcesInfo(memberId, "", "", "", "", null)), debt); + this(new FederationMember(new ResourcesInfo(memberId, "", "", "", "", "", "")), debt); } public FederationMemberDebt(FederationMember member, double debt) { diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/NoFPrioritizationPlugin.java b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/NoFPrioritizationPlugin.java index 214f6349..92897380 100644 --- a/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/NoFPrioritizationPlugin.java +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/NoFPrioritizationPlugin.java @@ -19,6 +19,7 @@ public class NoFPrioritizationPlugin implements PrioritizationPlugin { private AccountingPlugin accountingPlugin; private String localMemberId; private boolean trustworthy = false; + private boolean prioritizeLocal = true; private static final Logger LOGGER = Logger.getLogger(NoFPrioritizationPlugin.class); @@ -26,17 +27,28 @@ public NoFPrioritizationPlugin(Properties properties, AccountingPlugin accountin this.accountingPlugin = accountingPlugin; this.localMemberId = properties.getProperty(ConfigurationConstants.XMPP_JID_KEY); try { - this.trustworthy = Boolean.valueOf(properties.getProperty("nof_trustworthy")); + this.trustworthy = Boolean.valueOf(properties.getProperty("nof_trustworthy").trim()); } catch (Exception e) { - LOGGER.error("Error while getting boolean value for nof_trustworhty. The default value is false.", e); + LOGGER.error( + "Error while getting boolean value for nof_trustworhty. The default value is false.", + e); + } + + try { + this.prioritizeLocal = Boolean.valueOf(properties.getProperty("nof_prioritize_local") + .trim()); + } catch (Exception e) { + LOGGER.error( + "Error while getting boolean value for nof_prioritize_local. The default value is true.", + e); } } @Override - public Request takeFrom(String requestingMemberId, List requestsWithInstance) { + public Request takeFrom(Request newRequest, List requestsWithInstance) { LOGGER.debug("Choosing request to take instance from requestsWithInstance=" - + requestsWithInstance + " for requestMember=" + requestingMemberId); - if (localMemberId.equals(requestingMemberId) || requestsWithInstance == null) { + + requestsWithInstance + " for requestMember=" + newRequest.getRequestingMemberId()); + if (requestsWithInstance == null) { return null; } @@ -53,7 +65,8 @@ public Request takeFrom(String requestingMemberId, List requestsWithIns Collections.sort(memberDebts, new FederationMemberDebtComparator()); LOGGER.debug("Current memberDebts=" + memberDebts); - double requestingMemberDebt = calcDebt(membersUsage, requestingMemberId); + double requestingMemberDebt = calcDebt(membersUsage, newRequest.getRequestingMemberId()); + LOGGER.debug("Requesting member debt=" + requestingMemberDebt); FederationMemberDebt firstMember = memberDebts.getFirst(); if (firstMember.getDebt() < requestingMemberDebt) { String memberId = firstMember.getMember().getResourcesInfo().getId(); @@ -79,8 +92,7 @@ private LinkedList calctMemberDebts(List servedMem private List getServedMemberIds(List requests) { List servedMemberIds = new LinkedList(); for (Request currentRequest : requests) { - if (!currentRequest.isLocal() - && !servedMemberIds.contains(currentRequest.getRequestingMemberId())) { + if (!servedMemberIds.contains(currentRequest.getRequestingMemberId())) { servedMemberIds.add(currentRequest.getRequestingMemberId()); } } @@ -89,6 +101,14 @@ private List getServedMemberIds(List requests) { protected double calcDebt(Map membersUsage, String memberId) { double debt = 0; + if (localMemberId.equals(memberId)) { + if (prioritizeLocal) { + return Double.MAX_VALUE; + } else { + return -1; + } + } + if (membersUsage.containsKey(memberId)) { debt = membersUsage.get(memberId).getConsumed() - membersUsage.get(memberId).getDonated(); diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/util/CloudInitUserDataBuilder.java b/src/main/java/org/fogbowcloud/manager/core/plugins/util/CloudInitUserDataBuilder.java new file mode 100644 index 00000000..6a210269 --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/util/CloudInitUserDataBuilder.java @@ -0,0 +1,482 @@ +package org.fogbowcloud.manager.core.plugins.util; +/* + * Copyright 2008-2010 Xebia and the original author or authors. + * + * Licensed 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. + */ + + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.Set; + +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +import org.apache.commons.codec.binary.Base64; + +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; +import com.google.common.collect.Sets; +import com.google.common.io.CharStreams; + +/** + *

+ * Build a CloudInit + * UserData file. + *

+ *

+ * Sample: + *

+ * + *
+ * 
+ * // base64 encoded user data 
+ * String userData = CloudInitUserDataBuilder.start() //
+ *                      .addShellScript(shellScript) //
+ *                      .addCloudConfig(cloudConfig) //
+ *                      .buildBase64UserData();
+ * 
+ * RunInstancesRequest req = new RunInstancesRequest() //
+ *                              .withInstanceType("t1.micro") //
+ *                              .withImageId("ami-47cefa33") // amazon-linux in eu-west-1 region
+ *                              .withMinCount(1).withMaxCount(1) //
+ *                              .withSecurityGroupIds("default") //
+ *                              .withKeyName("my-key") //
+ *                              .withUserData(userData);
+ *                                               
+ * RunInstancesResult runInstances = ec2.runInstances(runInstancesRequest);
+ * 
+ * 
+ *

+ * Inspired by ubuntu-on-ec2 cloud-utils write-mime-multipart python script. + *

+ * + * @see com.amazonaws.services.ec2.model.RunInstancesRequest#withUserData(String) + * @see com.amazonaws.services.ec2.AmazonEC2.runInstances(RunInstancesRequest) + * + * @author Cyrille Le Clerc + */ +public class CloudInitUserDataBuilder { + + /** + * File types supported by CloudInit + */ + public enum FileType { + /** + *

+ * This content is "boothook" data. It is stored in a file under + * /var/lib/cloud and then executed immediately. This is the earliest + * "hook" available. Note, that there is no mechanism provided for + * running only once. The boothook must take care of this itself. It is + * provided with the instance id in the environment variable + * "INSTANCE_ID". This could be made use of to provide a + * 'once-per-instance' + *

+ */ + CLOUD_BOOTHOOK("text/cloud-boothook", "cloudinit-cloud-boothook.txt"), // + /** + *

+ * This content is "cloud-config" data. See the examples for a commented + * example of supported config formats. + *

+ *

+ * Example: cloud-config.txt + *

+ */ + CLOUD_CONFIG("text/cloud-config", "cloudinit-cloud-config.txt"), // + /** + *

+ * This content is a "include" file. The file contains a list of urls, + * one per line. Each of the URLs will be read, and their content will + * be passed through this same set of rules. Ie, the content read from + * the URL can be gzipped, mime-multi-part, or plain text + *

+ *

+ * Example: include.txt + *

+ */ + INCLUDE_URL("text/x-include-url", "cloudinit-x-include-url.txt"), // + /** + *

+ * This is a 'part-handler'. It will be written to a file in + * /var/lib/cloud/data based on its filename. This must be python code + * that contains a list_types method and a handle_type method. Once the + * section is read the 'list_types' method will be called. It must + * return a list of mime-types that this part-handler handlers. + *

+ *

+ * Example: part-handler.txt + *

+ */ + PART_HANDLER("text/part-handler", "cloudinit-part-handler.txt"), // + /** + *

+ * Script will be executed at "rc.local-like" level during first boot. + * rc.local-like means "very late in the boot sequence" + *

+ *

+ * Example: user-script.txt + *

+ */ + SHELL_SCRIPT("text/x-shellscript", "cloudinit-userdata-script.txt"), // + /** + *

+ * Content is placed into a file in /etc/init, and will be consumed by + * upstart as any other upstart job. + *

+ *

+ * Example: upstart-rclocal.txt + *

+ */ + UPSTART_JOB("text/upstart-job", "cloudinit-upstart-job.txt"); + + /** + * Name of the file. + */ + private final String fileName; + /** + * Mime Type of the file. + */ + private final String mimeType; + + private FileType( String mimeType, String fileName) { + this.mimeType = Preconditions.checkNotNull(mimeType); + this.fileName = Preconditions.checkNotNull(fileName); + } + + /** + * @return name of the file + */ + + public String getFileName() { + return fileName; + } + + /** + * e.g. "cloud-config" for "text/cloud-config" + */ + + public String getMimeTextSubType() { + return getMimeType().substring("text/".length()); + } + + /** + * e.g. "text/cloud-config" + */ + + public String getMimeType() { + return mimeType; + } + + @Override + public String toString() { + return name() + "[" + mimeType + "]"; + } + } + + /** + * Initiates a new instance of the builder with the "UTF-8" charset. + */ + public static CloudInitUserDataBuilder start() { + return new CloudInitUserDataBuilder(Charsets.UTF_8); + } + + /** + * Initiates a new instance of the builder. + * + * @param charset + * used to generate the mime message. + */ + public static CloudInitUserDataBuilder start( String charset) { + return new CloudInitUserDataBuilder(Charset.forName(charset)); + } + + /** + * File types already added because cloud-init only supports one file of + * each type. + */ + private final Set alreadyAddedFileTypes = Sets.newHashSet(); + + /** + * Charset used to generate the mime message. + */ + private final Charset charset; + + /** + * Mime message under creation + */ + private final MimeMessage userDataMimeMessage; + + /** + * Mime message's content under creation + */ + private final MimeMultipart userDataMultipart; + + private CloudInitUserDataBuilder( Charset charset) { + super(); + userDataMimeMessage = new MimeMessage(Session.getDefaultInstance(new Properties())); + userDataMultipart = new MimeMultipart(); + try { + userDataMimeMessage.setContent(userDataMultipart); + } catch (MessagingException e) { + throw Throwables.propagate(e); + } + this.charset = Preconditions.checkNotNull(charset, "'charset' can NOT be null"); + } + + /** + * Add a boot-hook file. + * + * @see FileType#CLOUD_BOOTHOOK + * @param bootHook + * @return the builder + * @throws IllegalArgumentException + * a boot-hook file was already added to this cloud-init mime + * message. + */ + public CloudInitUserDataBuilder addBootHook( Readable bootHook) { + return addFile(FileType.CLOUD_BOOTHOOK, bootHook); + } + + /** + * Add a cloud-config file. + * + * @see FileType#CLOUD_CONFIG + * @param cloudConfig + * @return the builder + * @throws IllegalArgumentException + * a cloud-config file was already added to this cloud-init mime + * message. + */ + public CloudInitUserDataBuilder addCloudConfig(Readable cloudConfig) { + return addFile(FileType.CLOUD_CONFIG, cloudConfig); + } + + /** + * Add a cloud-config file. + * + * @see FileType#CLOUD_CONFIG + * @param cloudConfig + * @return the builder + * @throws IllegalArgumentException + * a cloud-config file was already added to this cloud-init mime + * message. + */ + public CloudInitUserDataBuilder addCloudConfig(String cloudConfig) { + return addCloudConfig(new StringReader(cloudConfig)); + } + + /** + * Add given file in to the cloud-init mime message. + * + * @param fileType + * @param in + * file to add as readable + * @return the builder + * @throws IllegalArgumentException + * the given fileType was already added to this + * cloud-init mime message. + */ + + public CloudInitUserDataBuilder addFile( FileType fileType, Readable in) throws IllegalArgumentException { + Preconditions.checkNotNull(fileType, "'fileType' can NOT be null"); + Preconditions.checkNotNull(in, "'in' can NOT be null"); + Preconditions.checkArgument(!alreadyAddedFileTypes.contains(fileType), "%s as already been added", fileType); + alreadyAddedFileTypes.add(fileType); + + try { + StringWriter sw = new StringWriter(); + CharStreams.copy(in, sw); + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + mimeBodyPart.setText(sw.toString(), charset.name(), fileType.getMimeTextSubType()); + mimeBodyPart.setFileName(fileType.getFileName()); + userDataMultipart.addBodyPart(mimeBodyPart); + + } catch (IOException e) { + throw Throwables.propagate(e); + } catch (MessagingException e) { + throw Throwables.propagate(e); + } + return this; + } + + /** + * Add a include-url file. + * + * @see FileType#INCLUDE_URL + * @param includeUrl + * @return the builder + * @throws IllegalArgumentException + * a include-url file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addIncludeUrl( Readable includeUrl) { + return addFile(FileType.INCLUDE_URL, includeUrl); + } + + /** + * Add a include-url file. + * + * @see FileType#INCLUDE_URL + * @param includeUrl + * @return the builder + * @throws IllegalArgumentException + * a include-url file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addIncludeUrl( String includeUrl) { + return addIncludeUrl(new StringReader(includeUrl)); + } + + /** + * Add a part-handler file. + * + * @see FileType#PART_HANDLER + * @param partHandler + * @return the builder + * @throws IllegalArgumentException + * a part-handler file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addPartHandler( Readable partHandler) { + return addFile(FileType.PART_HANDLER, partHandler); + } + + /** + * Add a part-handler file. + * + * @see FileType#PART_HANDLER + * @param partHandler + * @return the builder + * @throws IllegalArgumentException + * a part-handler file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addPartHandler( String partHandler) { + return addPartHandler(new StringReader(partHandler)); + } + + /** + * Add a shell-script file. + * + * @see FileType#SHELL_SCRIPT + * @param shellScript + * @return the builder + * @throws IllegalArgumentException + * a shell-script file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addShellScript( Readable shellScript) { + return addFile(FileType.SHELL_SCRIPT, shellScript); + } + + /** + * Add a shell-script file. + * + * @see FileType#SHELL_SCRIPT + * @param shellScript + * @return the builder + * @throws IllegalArgumentException + * a shell-script file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addShellScript( String shellScript) { + return addShellScript(new StringReader(shellScript)); + } + + /** + * Add a upstart-job file. + * + * @see FileType#UPSTART_JOB + * @param shellScript + * @return the builder + * @throws IllegalArgumentException + * a upstart-job file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addUpstartJob( Readable in) { + return addFile(FileType.UPSTART_JOB, in); + } + + /** + * Add a upstart-job file. + * + * @see FileType#UPSTART_JOB + * @param shellScript + * @return the builder + * @throws IllegalArgumentException + * a upstart-job file was already added to this cloud-init mime + * message. + */ + + public CloudInitUserDataBuilder addUpstartJob( String upstartJob) { + return addUpstartJob(new StringReader(upstartJob)); + } + + /** + * Build the user-data mime message. + * + * @return the generate mime message + */ + + public String buildUserData() { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + userDataMimeMessage.writeTo(baos); + return new String(baos.toByteArray(), this.charset); + + } catch (MessagingException e) { + throw Throwables.propagate(e); + } catch (IOException e) { + throw Throwables.propagate(e); + } + } + + /** + * Build a base64 encoded user-data mime message. + * + * @return the base64 encoded encoded mime message + */ + + public String buildBase64UserData() { + return Base64.encodeBase64String(buildUserData().getBytes()); + } +} \ No newline at end of file diff --git a/src/main/java/org/fogbowcloud/manager/core/plugins/util/SshHelper.java b/src/main/java/org/fogbowcloud/manager/core/plugins/util/SshHelper.java new file mode 100644 index 00000000..814724d3 --- /dev/null +++ b/src/main/java/org/fogbowcloud/manager/core/plugins/util/SshHelper.java @@ -0,0 +1,93 @@ +package org.fogbowcloud.manager.core.plugins.util; + +import java.io.File; +import java.io.IOException; +import java.security.PublicKey; + +import net.schmizz.sshj.SSHClient; +import net.schmizz.sshj.connection.channel.direct.Session; +import net.schmizz.sshj.connection.channel.direct.Session.Command; +import net.schmizz.sshj.transport.verification.HostKeyVerifier; +import net.schmizz.sshj.xfer.FileSystemFile; +import net.schmizz.sshj.xfer.scp.SCPFileTransfer; + +public class SshHelper { + + private SSHClient client; + private Session session; + + public SshHelper() { + this(new SSHClient()); + } + + public SshHelper(SSHClient ssh) { + this.client = ssh; + addBlankHostKeyVerifier(client); + } + + private void addBlankHostKeyVerifier(SSHClient ssh) { + ssh.addHostKeyVerifier(new HostKeyVerifier() { + @Override + public boolean verify(String arg0, int arg1, PublicKey arg2) { + return true; + } + }); + } + + public SSHClient getSshClient() { + return client; + } + + public Command doSshExecution(String command) throws IOException { + session = client.startSession(); + Command cmd = session.exec(command); + cmd.join(); + return cmd; + } + + public void disconnect() throws IOException { + if (session != null) { + session.close(); + session = null; + } + client.disconnect(); + client.close(); + } + + public void doScpDownload(String localFilePath, String remoteFilePath) + throws IOException { + FileSystemFile localFile = new FileSystemFile(localFilePath); + client.newSCPFileTransfer().download(remoteFilePath, localFile); + } + + public void doScpUpload(String localFilePath, String remoteFilePath) + throws IOException { + doSshExecution("mkdir -p " + new File(remoteFilePath).getParent()); + FileSystemFile localFile = new FileSystemFile(localFilePath); + SCPFileTransfer scp = client.newSCPFileTransfer(); + scp.upload(localFile, remoteFilePath); + } + + public void connect(String host, int port, String userName, + String privateKeyFilePath, int timeOut) throws IOException { + client = new SSHClient(); + if (timeOut > 0) { + client.setConnectTimeout(timeOut); + } + addBlankHostKeyVerifier(client); + client.connect(host, port); + if (userName != null && privateKeyFilePath != null) { + client.authPublickey(userName, privateKeyFilePath); + } + } + + public void connect(String address, int port, String userName, + String privateKeyFilePath) throws IOException { + connect(address, port, userName, privateKeyFilePath, 0); + } + + public void connect(String address, int port) throws IOException { + connect(address, port, null, null, 0); + } + +} diff --git a/src/main/java/org/fogbowcloud/manager/occi/MemberServerResource.java b/src/main/java/org/fogbowcloud/manager/occi/MemberServerResource.java index 13c7a434..811582c8 100644 --- a/src/main/java/org/fogbowcloud/manager/occi/MemberServerResource.java +++ b/src/main/java/org/fogbowcloud/manager/occi/MemberServerResource.java @@ -1,9 +1,12 @@ package org.fogbowcloud.manager.occi; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; +import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.occi.core.HeaderUtils; import org.restlet.engine.adapter.HttpRequest; import org.restlet.resource.Get; @@ -28,24 +31,19 @@ public String fetch() { private String generateResponse(List federationMembers) { StringBuilder response = new StringBuilder(); for (FederationMember federationMember : federationMembers) { - String id = federationMember.getResourcesInfo().getId(); - response.append("id=").append(id).append(";"); - String cpuIdle = federationMember.getResourcesInfo().getCpuIdle(); - response.append("cpuIdle=").append(cpuIdle).append(";"); - String cpuInUse = federationMember.getResourcesInfo().getCpuInUse(); - response.append("cpuInUse=").append(cpuInUse).append(";"); - String memIdle = federationMember.getResourcesInfo().getMemIdle(); - response.append("memIdle=").append(memIdle).append(";"); - String memInUse = federationMember.getResourcesInfo().getMemInUse(); - response.append("memInUse=").append(memInUse).append(";"); + Map resourcesInfoMap = new HashMap(); + ResourcesInfo resourcesInfo = federationMember.getResourcesInfo(); + resourcesInfoMap.put("id", resourcesInfo.getId()); + resourcesInfoMap.put("cpuIdle", resourcesInfo.getCpuIdle()); + resourcesInfoMap.put("cpuInUse", resourcesInfo.getCpuInUse()); + resourcesInfoMap.put("memIdle", resourcesInfo.getMemIdle()); + resourcesInfoMap.put("memInUse", resourcesInfo.getMemInUse()); + resourcesInfoMap.put("instancesIdle", resourcesInfo.getInstancesIdle()); + resourcesInfoMap.put("instancesInUse", resourcesInfo.getInstancesInUse()); - if (federationMember.getResourcesInfo().getFlavors() != null) { - for (Flavor flavor : federationMember.getResourcesInfo().getFlavors()) { - String nameFlavor = flavor.getName(); - Integer capacityFlavor = flavor.getCapacity(); - response.append("flavor: '").append(nameFlavor).append(", capacity=\"") - .append(capacityFlavor).append("\"';"); - } + for (Entry resourceInfoEntry : resourcesInfoMap.entrySet()) { + response.append(resourceInfoEntry.getKey()).append("=") + .append(resourceInfoEntry.getValue()).append(";"); } response.append("\n"); } diff --git a/src/main/java/org/fogbowcloud/manager/occi/instance/Instance.java b/src/main/java/org/fogbowcloud/manager/occi/instance/Instance.java index 4f8ca300..02e77497 100644 --- a/src/main/java/org/fogbowcloud/manager/occi/instance/Instance.java +++ b/src/main/java/org/fogbowcloud/manager/occi/instance/Instance.java @@ -13,6 +13,7 @@ public class Instance { public static final String PREFIX_DEFAULT_INSTANCE = "X-OCCI-Location: "; public static final String SSH_PUBLIC_ADDRESS_ATT = "org.fogbowcloud.request.ssh-public-address"; + public static final String SSH_USERNAME_ATT = "org.fogbowcloud.request.ssh-username"; private static final String PREFIX_DEFAULT_ATTRIBUTE = "X-OCCI-Attribute: "; private static final String CATEGORY = "Category:"; diff --git a/src/main/java/org/fogbowcloud/manager/occi/request/Request.java b/src/main/java/org/fogbowcloud/manager/occi/request/Request.java index 23bbf1af..6729050e 100644 --- a/src/main/java/org/fogbowcloud/manager/occi/request/Request.java +++ b/src/main/java/org/fogbowcloud/manager/occi/request/Request.java @@ -48,6 +48,11 @@ public Request(String id, Token federationToken, Token localToken, this.dateUtils = dateUtils; setState(RequestState.OPEN); } + + public Request(Request request) { + this(request.getId(), request.getFederationToken(), request.getLocalToken(), request.getCategories(), + request.getxOCCIAtt(), request.isLocal, request.getRequestingMemberId()); + } public List getCategories() { if (categories == null) { @@ -199,4 +204,5 @@ public boolean isExpired() { long now = new DateUtils().currentTimeMillis(); return expirationDate.getTime() < now; } + } \ No newline at end of file diff --git a/src/main/java/org/fogbowcloud/manager/xmpp/ManagerPacketHelper.java b/src/main/java/org/fogbowcloud/manager/xmpp/ManagerPacketHelper.java index 5afca3c7..7d539a4f 100644 --- a/src/main/java/org/fogbowcloud/manager/xmpp/ManagerPacketHelper.java +++ b/src/main/java/org/fogbowcloud/manager/xmpp/ManagerPacketHelper.java @@ -3,7 +3,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -15,7 +14,6 @@ import org.dom4j.Element; import org.fogbowcloud.manager.core.AsynchronousRequestCallback; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.occi.core.Category; import org.fogbowcloud.manager.occi.core.ErrorType; @@ -54,14 +52,8 @@ public static void iAmAlive(ResourcesInfo resourcesInfo, String rendezvousAddres statusEl.addElement("cpu-inuse").setText(resourcesInfo.getCpuInUse()); statusEl.addElement("mem-idle").setText(resourcesInfo.getMemIdle()); statusEl.addElement("mem-inuse").setText(resourcesInfo.getMemInUse()); - List flavours = resourcesInfo.getFlavors(); - for (Flavor f : flavours) { - Element flavorElement = statusEl.addElement("flavor"); - flavorElement.addElement("name").setText(f.getName()); - flavorElement.addElement("cpu").setText(f.getCpu()); - flavorElement.addElement("mem").setText(f.getMem()); - flavorElement.addElement("capacity").setText(f.getCapacity().toString()); - } + statusEl.addElement("instances-idle").setText(resourcesInfo.getInstancesIdle()); + statusEl.addElement("instances-inuse").setText(resourcesInfo.getInstancesInUse()); packetSender.syncSendPacket(iq); } @@ -122,52 +114,44 @@ private static ArrayList getMembersFromIQ(IQ responseFromWhoIs Attribute id = itemEl.attribute("id"); Element statusEl = itemEl.element("status"); - String cpuIdle = statusEl.element("cpu-idle").getText(); - String cpuInUse = statusEl.element("cpu-inuse").getText(); - String memIdle = statusEl.element("mem-idle").getText(); - String memInUse = statusEl.element("mem-inuse").getText(); - - List flavoursList = new LinkedList(); - Iterator flavourIterator = statusEl.elementIterator("flavor"); - while (flavourIterator.hasNext()) { - Element flavour = (Element) flavourIterator.next(); - String name = flavour.element("name").getText(); - String cpu = flavour.element("cpu").getText(); - String mem = flavour.element("mem").getText(); - int capacity = Integer.parseInt(flavour.element("capacity").getText()); - Flavor flavor = new Flavor(name, cpu, mem, capacity); - flavoursList.add(flavor); - } + String cpuIdle = statusEl.elementText("cpu-idle"); + String cpuInUse = statusEl.elementText("cpu-inuse"); + String memIdle = statusEl.elementText("mem-idle"); + String memInUse = statusEl.elementText("mem-inuse"); + String instancesIdle = statusEl.elementText("instances-idle"); + String instancesInUse = statusEl.elementText("instances-inuse"); ResourcesInfo resources = new ResourcesInfo(id.getValue(), cpuIdle, cpuInUse, memIdle, - memInUse, flavoursList); + memInUse, instancesIdle, instancesInUse); FederationMember item = new FederationMember(resources); aliveItems.add(item); } return aliveItems; } - public static void asynchronousRemoteRequest(Request request, String memberAddress, - Token userFederationToken, AsyncPacketSender packetSender, final AsynchronousRequestCallback callback) { + public static void asynchronousRemoteRequest(String requestId, List categories, + Map xOCCIAttr, String memberAddress, + Token userFederationToken, AsyncPacketSender packetSender, + final AsynchronousRequestCallback callback) { IQ iq = new IQ(); - iq.setID(request.getId()); + iq.setID(requestId); iq.setTo(memberAddress); iq.setType(Type.set); Element queryEl = iq.getElement().addElement("query", ManagerXmppComponent.REQUEST_NAMESPACE); - for (Category category : request.getCategories()) { + for (Category category : categories) { Element categoryEl = queryEl.addElement("category"); categoryEl.addElement("class").setText(category.getCatClass()); categoryEl.addElement("term").setText(category.getTerm()); categoryEl.addElement("scheme").setText(category.getScheme()); } - for (Entry xOCCIEntry : request.getxOCCIAtt().entrySet()) { + for (Entry xOCCIEntry : xOCCIAttr.entrySet()) { Element attributeEl = queryEl.addElement("attribute"); attributeEl.addAttribute("var", xOCCIEntry.getKey()); attributeEl.addElement("value").setText(xOCCIEntry.getValue()); } Element requestEl = queryEl.addElement("request"); - requestEl.addElement("id").setText(request.getId()); + requestEl.addElement("id").setText(requestId); if (userFederationToken != null) { Element tokenEl = queryEl.addElement("token"); diff --git a/src/test/java/org/fogbowcloud/manager/core/TestForwardedToken.java b/src/test/java/org/fogbowcloud/manager/core/TestForwardedToken.java index 3dab75dc..ba6b2942 100644 --- a/src/test/java/org/fogbowcloud/manager/core/TestForwardedToken.java +++ b/src/test/java/org/fogbowcloud/manager/core/TestForwardedToken.java @@ -36,7 +36,8 @@ public void testTokenBeingForwarded() { new HashMap(), true, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); request1.setState(RequestState.OPEN); - ManagerPacketHelper.asynchronousRemoteRequest(request1, "member1", new Token("accessId", "user", + ManagerPacketHelper.asynchronousRemoteRequest(request1.getId(), request1.getCategories(), + request1.getxOCCIAtt(), "member1", new Token("accessId", "user", null, null), packetSender, null); Mockito.verify(packetSender).sendPacket(Mockito.argThat(new ArgumentMatcher() { @@ -63,7 +64,8 @@ public void testTokenNotBeingForwarded() { new HashMap(), true, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); request1.setState(RequestState.OPEN); - ManagerPacketHelper.asynchronousRemoteRequest(request1, "member1", null, packetSender, null); + ManagerPacketHelper.asynchronousRemoteRequest(request1.getId(), request1.getCategories(), + request1.getxOCCIAtt(), "member1", null, packetSender, null); Mockito.verify(packetSender).sendPacket(Mockito.argThat(new ArgumentMatcher() { @Override diff --git a/src/test/java/org/fogbowcloud/manager/core/TestManagerController.java b/src/test/java/org/fogbowcloud/manager/core/TestManagerController.java index 997e0103..e448613d 100644 --- a/src/test/java/org/fogbowcloud/manager/core/TestManagerController.java +++ b/src/test/java/org/fogbowcloud/manager/core/TestManagerController.java @@ -1,5 +1,8 @@ package org.fogbowcloud.manager.core; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.security.cert.CertificateException; import java.util.ArrayList; @@ -9,6 +12,12 @@ import java.util.List; import java.util.Map; +import javax.mail.MessagingException; + +import net.schmizz.sshj.connection.channel.direct.Session.Command; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; import org.dom4j.Element; import org.fogbowcloud.manager.core.model.DateUtils; import org.fogbowcloud.manager.core.model.FederationMember; @@ -19,6 +28,7 @@ import org.fogbowcloud.manager.core.plugins.IdentityPlugin; import org.fogbowcloud.manager.core.plugins.openstack.KeystoneIdentityPlugin; import org.fogbowcloud.manager.core.plugins.openstack.OpenStackOCCIComputePlugin; +import org.fogbowcloud.manager.core.plugins.util.SshHelper; import org.fogbowcloud.manager.core.util.DefaultDataTestHelper; import org.fogbowcloud.manager.core.util.ManagerTestHelper; import org.fogbowcloud.manager.occi.core.Category; @@ -116,7 +126,7 @@ public void testSubmitLocalUserRequests() throws InterruptedException { @SuppressWarnings("unchecked") @Test public void testSubmitFederationUserRequests() throws InterruptedException { - ResourcesInfo resourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo resourcesInfo = new ResourcesInfo("", "", "", "", "", ""); resourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -172,7 +182,7 @@ public void testSubmitToGreenSitter() { ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); Mockito.when( @@ -242,10 +252,10 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(packetSender).addPacketCallback(Mockito.any(Packet.class), Mockito.any(PacketCallback.class)); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); remoteResourcesInfo.setId(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -301,10 +311,10 @@ public void testRemoveForwardedRequestAfterTimeout() throws InterruptedException AsyncPacketSender packetSender = Mockito.mock(AsyncPacketSender.class); managerController.setPacketSender(packetSender); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); remoteResourcesInfo.setId(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -375,10 +385,10 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(packetSender).addPacketCallback(Mockito.any(Packet.class), Mockito.any(PacketCallback.class)); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); remoteResourcesInfo.setId(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -444,10 +454,10 @@ public Void answer(InvocationOnMock invocation) throws Throwable { } }).when(packetSender).addPacketCallback(Mockito.any(Packet.class), Mockito.any(PacketCallback.class)); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); remoteResourcesInfo.setId(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -1569,6 +1579,7 @@ public void testPersistentRequestValidityPeriodInFuture() throws InterruptedExce Assert.assertNull(requests.get(0).getProvidingMemberId()); } + @SuppressWarnings("unchecked") @Test public void testSubmitRequestForRemoteMemberValidation() { ResourcesInfo resources = Mockito.mock(ResourcesInfo.class); @@ -1809,9 +1820,9 @@ public void testGetFlavors() { @Test public void testGetAllowedFederationMembers() { - ResourcesInfo resourcesInfoOne = new ResourcesInfo("id1","", "", "", "", null); - ResourcesInfo resourcesInfoTwo = new ResourcesInfo("id2","", "", "", "", null); - ResourcesInfo resourcesInfoThree = new ResourcesInfo("id3","", "", "", "", null); + ResourcesInfo resourcesInfoOne = new ResourcesInfo("id1","", "", "", "", "", ""); + ResourcesInfo resourcesInfoTwo = new ResourcesInfo("id2","", "", "", "", "", ""); + ResourcesInfo resourcesInfoThree = new ResourcesInfo("id3","", "", "", "", "", ""); List listMembers = new ArrayList(); listMembers.add(new FederationMember(resourcesInfoOne)); @@ -1826,9 +1837,9 @@ public void testGetAllowedFederationMembers() { @Test public void testGetAllowedFederationMembersWithRequirements() { - ResourcesInfo resourcesInfoOne = new ResourcesInfo("id1","", "", "", "", null); - ResourcesInfo resourcesInfoTwo = new ResourcesInfo("id2","", "", "", "", null); - ResourcesInfo resourcesInfoThree = new ResourcesInfo("id3","", "", "", "", null); + ResourcesInfo resourcesInfoOne = new ResourcesInfo("id1","", "", "", "", "", ""); + ResourcesInfo resourcesInfoTwo = new ResourcesInfo("id2","", "", "", "", "", ""); + ResourcesInfo resourcesInfoThree = new ResourcesInfo("id3","", "", "", "", "", ""); List listMembers = new ArrayList(); listMembers.add(new FederationMember(resourcesInfoOne)); @@ -1886,10 +1897,10 @@ public void testInstanceIsNotBeingUsedButRequestWasForwarded(){ AsyncPacketSender packetSender = Mockito.mock(AsyncPacketSender.class); managerController.setPacketSender(packetSender); - ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); localResourcesInfo.setId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", null); + ResourcesInfo remoteResourcesInfo = new ResourcesInfo("", "", "", "", "", ""); remoteResourcesInfo.setId(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); @@ -2213,7 +2224,370 @@ public void testGarbageCollectorWithServedRequest() { } @Test - public void testPreemption(){ + @SuppressWarnings("unchecked") + public void testSSHKeyReplacementWhenOriginalRequestHasPublicKey() + throws FileNotFoundException, IOException, MessagingException { + Map extraProperties = new HashMap(); + extraProperties.put(ConfigurationConstants.SSH_PUBLIC_KEY_PATH, + DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH); + ManagerController localManagerController = + managerTestHelper.createDefaultManagerController(extraProperties); + ManagerController spiedManageController = Mockito.spy(localManagerController); + String remoteRequestId = "id1"; + + SshHelper sshHelper = createFakeSSHHelper(); + Mockito.doReturn(sshHelper).when(spiedManageController).createSshHelper(); + + Map newXOCCIAttr = new HashMap(this.xOCCIAtt); + ArrayList categories = new ArrayList(); + final Category publicKeyCategory = new Category(RequestConstants.PUBLIC_KEY_TERM, + RequestConstants.CREDENTIALS_RESOURCE_SCHEME, RequestConstants.MIXIN_CLASS); + categories.add(publicKeyCategory); + newXOCCIAttr.put(RequestAttribute.DATA_PUBLIC_KEY.getValue(), "public-key"); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String newInstanceId = "newinstanceid"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), + Mockito.anyList(), Mockito.anyMap(), Mockito.anyString())).thenReturn(newInstanceId); + spiedManageController.setComputePlugin(computePlugin); + + Request servedRequest = new Request(remoteRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), categories, + newXOCCIAttr, true, + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); + servedRequest.setState(RequestState.FULFILLED); + servedRequest.setInstanceId(newInstanceId); + servedRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + Instance instance = new Instance(newInstanceId); + instance.addAttribute(Instance.SSH_PUBLIC_ADDRESS_ATT, "127.0.0.1:5555"); + instance.addAttribute(Instance.SSH_USERNAME_ATT, "fogbow"); + + Mockito.when(computePlugin.getInstance(Mockito.any(Token.class), + Mockito.eq(newInstanceId))).thenReturn(instance); + + spiedManageController.createInstanceWithFederationUser(servedRequest); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + Mockito.verify(computePlugin).requestInstance(Mockito.any(Token.class), + Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + List categories = (List) argument; + return !categories.contains(publicKeyCategory); + } + }), Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + Map xOCCIAttr = (Map) argument; + String publicKeyValue = xOCCIAttr + .get(RequestAttribute.DATA_PUBLIC_KEY + .getValue()); + return publicKeyValue == null; + } + }), Mockito.anyString()); + + String base64UserDataCmd = new String(Base64.decodeBase64(localManagerController + .createUserDataUtilsCommand(servedRequest)), "UTF-8"); + Assert.assertTrue(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + @Test + @SuppressWarnings("unchecked") + public void testSSHKeyReplacementWhenOriginalRequestHasNoPublicKey() + throws FileNotFoundException, IOException, MessagingException { + Map extraProperties = new HashMap(); + extraProperties.put(ConfigurationConstants.SSH_PUBLIC_KEY_PATH, + DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH); + ManagerController localManagerController = + managerTestHelper.createDefaultManagerController(extraProperties); + String remoteRequestId = "id1"; + ManagerController spiedManageController = Mockito.spy(localManagerController); + + SshHelper sshHelper = createFakeSSHHelper(); + Mockito.doReturn(sshHelper).when(spiedManageController).createSshHelper(); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String newInstanceId = "newinstanceid"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), + Mockito.anyList(), Mockito.anyMap(), Mockito.anyString())).thenReturn(newInstanceId); + spiedManageController.setComputePlugin(computePlugin); + + Request servedRequest = new Request(remoteRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), new ArrayList(), + xOCCIAtt, true, + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); + servedRequest.setState(RequestState.FULFILLED); + servedRequest.setInstanceId(newInstanceId); + servedRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + Instance instance = new Instance(newInstanceId); + instance.addAttribute(Instance.SSH_PUBLIC_ADDRESS_ATT, "127.0.0.1:5555"); + instance.addAttribute(Instance.SSH_USERNAME_ATT, "fogbow"); + + Mockito.when(computePlugin.getInstance(Mockito.any(Token.class), + Mockito.eq(newInstanceId))).thenReturn(instance); + + spiedManageController.createInstanceWithFederationUser(servedRequest); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + final Category publicKeyCategory = new Category(RequestConstants.PUBLIC_KEY_TERM, + RequestConstants.CREDENTIALS_RESOURCE_SCHEME, RequestConstants.MIXIN_CLASS); + + Mockito.verify(computePlugin).requestInstance(Mockito.any(Token.class), + Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + List categories = (List) argument; + return !categories.contains(publicKeyCategory); + } + }), Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + Map xOCCIAttr = (Map) argument; + String publicKeyValue = xOCCIAttr + .get(RequestAttribute.DATA_PUBLIC_KEY + .getValue()); + return publicKeyValue == null; + } + }), Mockito.anyString()); + + String base64UserDataCmd = new String(Base64.decodeBase64(localManagerController + .createUserDataUtilsCommand(servedRequest)), "UTF-8"); + Assert.assertTrue(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + @SuppressWarnings("unchecked") + @Test + public void testSSHKeyReplacementWhenManagerKeyIsNotDefined() + throws FileNotFoundException, IOException, MessagingException { + ManagerController managerControllerSpy = Mockito.spy(managerController); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String instanceId = "instance1"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), Mockito.anyList(), + Mockito.anyMap(), Mockito.anyString())).thenReturn(instanceId); + managerControllerSpy.setComputePlugin(computePlugin); + + String servedRequestId = "id1"; + Request servedRequest = new Request(servedRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), new ArrayList(), + xOCCIAtt, true, + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL); + servedRequest.setState(RequestState.FULFILLED); + servedRequest.setInstanceId(instanceId); + servedRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + managerControllerSpy.createInstanceWithFederationUser(servedRequest); + + Mockito.verify(managerControllerSpy, Mockito.never()).waitForSSHPublicAddress(Mockito.eq(servedRequest)); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + String base64UserDataCmd = new String(Base64.decodeBase64(managerController + .createUserDataUtilsCommand(servedRequest)), "UTF-8"); + Assert.assertFalse(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + @Test + @SuppressWarnings("unchecked") + public void testSSHKeyReplacementLocallyWhenOriginalRequestHasPublicKey() throws FileNotFoundException, IOException, MessagingException { + Map extraProperties = new HashMap(); + extraProperties.put(ConfigurationConstants.SSH_PUBLIC_KEY_PATH, + DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH); + ManagerController localManagerController = + managerTestHelper.createDefaultManagerController(extraProperties); + ManagerController spiedManageController = Mockito.spy(localManagerController); + + SshHelper sshHelper = createFakeSSHHelper(); + Mockito.doReturn(sshHelper).when(spiedManageController).createSshHelper(); + + String localRequestId = "id1"; + + Map newXOCCIAttr = new HashMap(this.xOCCIAtt); + ArrayList categories = new ArrayList(); + final Category publicKeyCategory = new Category(RequestConstants.PUBLIC_KEY_TERM, + RequestConstants.CREDENTIALS_RESOURCE_SCHEME, RequestConstants.MIXIN_CLASS); + categories.add(publicKeyCategory); + newXOCCIAttr.put(RequestAttribute.DATA_PUBLIC_KEY.getValue(), "public-key"); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String newInstanceId = "newinstanceid"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), + Mockito.anyList(), Mockito.anyMap(), Mockito.anyString())).thenReturn(newInstanceId); + spiedManageController.setComputePlugin(computePlugin); + + Request localRequest = new Request(localRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), categories, + newXOCCIAttr, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + localRequest.setState(RequestState.FULFILLED); + localRequest.setInstanceId(newInstanceId); + localRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + Instance instance = new Instance(newInstanceId); + instance.addAttribute(Instance.SSH_PUBLIC_ADDRESS_ATT, "127.0.0.1:5555"); + instance.addAttribute(Instance.SSH_USERNAME_ATT, "fogbow"); + + Mockito.when(computePlugin.getInstance(Mockito.any(Token.class), + Mockito.eq(newInstanceId))).thenReturn(instance); + + spiedManageController.createInstanceWithFederationUser(localRequest); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + Mockito.verify(computePlugin).requestInstance(Mockito.any(Token.class), + Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + List categories = (List) argument; + return !categories.contains(publicKeyCategory); + } + }), Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + Map xOCCIAttr = (Map) argument; + String publicKeyValue = xOCCIAttr + .get(RequestAttribute.DATA_PUBLIC_KEY + .getValue()); + return publicKeyValue == null; + } + }), Mockito.anyString()); + + String base64UserDataCmd = new String(Base64.decodeBase64(localManagerController + .createUserDataUtilsCommand(localRequest)), "UTF-8"); + Assert.assertTrue(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + private SshHelper createFakeSSHHelper() throws IOException { + SshHelper sshHelper = Mockito.mock(SshHelper.class); + Command command = Mockito.mock(Command.class); + Mockito.when(command.getExitStatus()).thenReturn(0); + Mockito.when(sshHelper.doSshExecution(Mockito.anyString())).thenReturn(command); + return sshHelper; + } + + @Test + @SuppressWarnings("unchecked") + public void testSSHKeyReplacementLocallyWhenOriginalRequestHasNoPublicKey() + throws FileNotFoundException, IOException, MessagingException { + Map extraProperties = new HashMap(); + extraProperties.put(ConfigurationConstants.SSH_PUBLIC_KEY_PATH, + DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH); + ManagerController localManagerController = + managerTestHelper.createDefaultManagerController(extraProperties); + String localRequestId = "id1"; + ManagerController spiedManageController = Mockito.spy(localManagerController); + + SshHelper sshHelper = createFakeSSHHelper(); + Mockito.doReturn(sshHelper).when(spiedManageController).createSshHelper(); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String newInstanceId = "newinstanceid"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), + Mockito.anyList(), Mockito.anyMap(), Mockito.anyString())).thenReturn(newInstanceId); + spiedManageController.setComputePlugin(computePlugin); + + Request localRequest = new Request(localRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), new ArrayList(), + xOCCIAtt, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + localRequest.setState(RequestState.FULFILLED); + localRequest.setInstanceId(newInstanceId); + localRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + Instance instance = new Instance(newInstanceId); + instance.addAttribute(Instance.SSH_PUBLIC_ADDRESS_ATT, "127.0.0.1:5555"); + instance.addAttribute(Instance.SSH_USERNAME_ATT, "fogbow"); + + Mockito.when(computePlugin.getInstance(Mockito.any(Token.class), + Mockito.eq(newInstanceId))).thenReturn(instance); + + spiedManageController.createInstanceWithFederationUser(localRequest); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + final Category publicKeyCategory = new Category(RequestConstants.PUBLIC_KEY_TERM, + RequestConstants.CREDENTIALS_RESOURCE_SCHEME, RequestConstants.MIXIN_CLASS); + + Mockito.verify(computePlugin).requestInstance(Mockito.any(Token.class), + Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + List categories = (List) argument; + return !categories.contains(publicKeyCategory); + } + }), Mockito.argThat(new ArgumentMatcher>() { + + @Override + public boolean matches(Object argument) { + Map xOCCIAttr = (Map) argument; + String publicKeyValue = xOCCIAttr + .get(RequestAttribute.DATA_PUBLIC_KEY + .getValue()); + return publicKeyValue == null; + } + }), Mockito.anyString()); + + String base64UserDataCmd = new String(Base64.decodeBase64(localManagerController + .createUserDataUtilsCommand(localRequest)), "UTF-8"); + Assert.assertTrue(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + @SuppressWarnings("unchecked") + @Test + public void testSSHKeyReplacementLocallyWhenManagerKeyIsNotDefined() + throws FileNotFoundException, IOException, MessagingException { + ManagerController managerControllerSpy = Mockito.spy(managerController); + + ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class); + String instanceId = "instance1"; + Mockito.when( + computePlugin.requestInstance(Mockito.any(Token.class), Mockito.anyList(), + Mockito.anyMap(), Mockito.anyString())).thenReturn(instanceId); + managerControllerSpy.setComputePlugin(computePlugin); + + String localRequestId = "id1"; + Request localRequest = new Request(localRequestId, managerTestHelper.getDefaultFederationToken(), + managerTestHelper.getDefaultLocalToken(), new ArrayList(), + xOCCIAtt, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + localRequest.setState(RequestState.FULFILLED); + localRequest.setInstanceId(instanceId); + localRequest.setProvidingMemberId(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + managerControllerSpy.createInstanceWithFederationUser(localRequest); + + Mockito.verify(managerControllerSpy, Mockito.never()).waitForSSHPublicAddress(Mockito.eq(localRequest)); + + final String localManagerPublicKeyData = IOUtils.toString(new FileInputStream( + new File(DefaultDataTestHelper.LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH))); + + String base64UserDataCmd = new String(Base64.decodeBase64(managerController + .createUserDataUtilsCommand(localRequest)), "UTF-8"); + Assert.assertFalse(base64UserDataCmd.contains(localManagerPublicKeyData)); + } + + public void testPreemption() { Request localRequest = new Request("id1", managerTestHelper.getDefaultFederationToken(), managerTestHelper.getDefaultLocalToken(), new ArrayList(), new HashMap(), true, @@ -2278,5 +2652,6 @@ public void testPreemption(){ Assert.assertTrue(requestRepository.getAllRemoteRequests().isEmpty()); Assert.assertFalse(requestRepository.getAllRemoteRequests().contains(servedRequest1)); Assert.assertFalse(requestRepository.getAllRemoteRequests().contains(servedRequest2)); - } + } + } diff --git a/src/test/java/org/fogbowcloud/manager/core/TestNoFMemberPicker.java b/src/test/java/org/fogbowcloud/manager/core/TestNoFMemberPicker.java index 285992ba..351cf9cb 100644 --- a/src/test/java/org/fogbowcloud/manager/core/TestNoFMemberPicker.java +++ b/src/test/java/org/fogbowcloud/manager/core/TestNoFMemberPicker.java @@ -48,7 +48,7 @@ public void testEmptyMembers() { public void testOnlyLocalMember() { // mocking FederationMember localMember = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", null)); + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", "", "")); ArrayList membersToReturn = new ArrayList(); membersToReturn.add(localMember); @@ -65,9 +65,9 @@ public void testOnlyLocalMember() { public void testOneRemoteMember() { // mocking facade FederationMember localMember = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", null)); + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", "", "")); FederationMember remoteMember = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL, "", "", "", "", null)); + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL, "", "", "", "", "", "")); ArrayList membersToReturn = new ArrayList(); membersToReturn.add(localMember); membersToReturn.add(remoteMember); @@ -91,11 +91,11 @@ public void testOneRemoteMember() { public void testTwoRemoteMembers() { // mocking facade FederationMember localMember = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", null)); + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", "", "")); FederationMember remoteMember1 = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "1", "", "", "", "", null)); + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "1", "", "", "", "", "", "")); FederationMember remoteMember2 = new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "2", "", "", "", "", null)); + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "2", "", "", "", "", "", "")); ArrayList membersToReturn = new ArrayList(); membersToReturn.add(localMember); membersToReturn.add(remoteMember1); diff --git a/src/test/java/org/fogbowcloud/manager/core/TestRoundRobinMemberPicker.java b/src/test/java/org/fogbowcloud/manager/core/TestRoundRobinMemberPicker.java index 8b524073..0984ac60 100644 --- a/src/test/java/org/fogbowcloud/manager/core/TestRoundRobinMemberPicker.java +++ b/src/test/java/org/fogbowcloud/manager/core/TestRoundRobinMemberPicker.java @@ -21,11 +21,11 @@ public void testListMembersNull() { public void testPick() { RoundRobinMemberPicker roundRobinMemberPicker = new RoundRobinMemberPicker(null, null); List members = new ArrayList(); - ResourcesInfo resourcesInfoD = new ResourcesInfo("d", "", "", "", "", null); - ResourcesInfo resourcesInfoA = new ResourcesInfo("a", "", "", "", "", null); - ResourcesInfo resourcesInfoCA = new ResourcesInfo("ca", "", "", "", "", null); - ResourcesInfo resourcesInfoCB = new ResourcesInfo("cb", "", "", "", "", null); - ResourcesInfo resourcesInfoB = new ResourcesInfo("b", "", "", "", "", null); + ResourcesInfo resourcesInfoD = new ResourcesInfo("d", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoA = new ResourcesInfo("a", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoCA = new ResourcesInfo("ca", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoCB = new ResourcesInfo("cb", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoB = new ResourcesInfo("b", "", "", "", "", "", ""); members.add(new FederationMember(resourcesInfoA)); members.add(new FederationMember(resourcesInfoCB)); members.add(new FederationMember(resourcesInfoCA)); @@ -72,11 +72,11 @@ public void testPick() { public void testPickListMemberWithoutLastMember() { RoundRobinMemberPicker roundRobinMemberPicker = new RoundRobinMemberPicker(null, null); List members = new ArrayList(); - ResourcesInfo resourcesInfoD = new ResourcesInfo("d", "", "", "", "", null); - ResourcesInfo resourcesInfoA = new ResourcesInfo("a", "", "", "", "", null); - ResourcesInfo resourcesInfoCA = new ResourcesInfo("ca", "", "", "", "", null); - ResourcesInfo resourcesInfoCB = new ResourcesInfo("cb", "", "", "", "", null); - ResourcesInfo resourcesInfoB = new ResourcesInfo("b", "", "", "", "", null); + ResourcesInfo resourcesInfoD = new ResourcesInfo("d", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoA = new ResourcesInfo("a", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoCA = new ResourcesInfo("ca", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoCB = new ResourcesInfo("cb", "", "", "", "", "", ""); + ResourcesInfo resourcesInfoB = new ResourcesInfo("b", "", "", "", "", "", ""); members.add(new FederationMember(resourcesInfoA)); members.add(new FederationMember(resourcesInfoCB)); members.add(new FederationMember(resourcesInfoCA)); diff --git a/src/test/java/org/fogbowcloud/manager/core/plugins/accounting/TestFCUAccounting.java b/src/test/java/org/fogbowcloud/manager/core/plugins/accounting/TestFCUAccounting.java index 6b1e2325..3e9514ac 100644 --- a/src/test/java/org/fogbowcloud/manager/core/plugins/accounting/TestFCUAccounting.java +++ b/src/test/java/org/fogbowcloud/manager/core/plugins/accounting/TestFCUAccounting.java @@ -1,13 +1,11 @@ package org.fogbowcloud.manager.core.plugins.accounting; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Properties; -import org.apache.commons.io.FileUtils; import org.fogbowcloud.manager.core.ConfigurationConstants; import org.fogbowcloud.manager.core.model.DateUtils; import org.fogbowcloud.manager.core.plugins.BenchmarkingPlugin; @@ -24,17 +22,14 @@ public class TestFCUAccounting { private static final double ACCEPTABLE_ERROR = 0.0; private BenchmarkingPlugin benchmarkingPlugin; - private final String DATASTORE_PATH = "src/test/resources/accounting"; FCUAccountingPlugin accountingPlugin; Properties properties; @Before public void setUp() throws IOException { - new File(DATASTORE_PATH).mkdir(); benchmarkingPlugin = Mockito.mock(BenchmarkingPlugin.class); properties = new Properties(); - properties.put("accounting_datastore_url", "jdbc:h2:mem:" - + new File(DATASTORE_PATH).getAbsolutePath() + "usage"); + properties.put("accounting_datastore_url", "jdbc:h2:mem:usage"); properties.put(ConfigurationConstants.XMPP_JID_KEY, "localMemberId"); accountingPlugin = new FCUAccountingPlugin(properties, benchmarkingPlugin); @@ -43,7 +38,6 @@ public void setUp() throws IOException { @After public void tearDown() throws IOException { - FileUtils.cleanDirectory(new File(DATASTORE_PATH)); accountingPlugin.getDatabase().dispose(); } diff --git a/src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestFCUStaticBenchmarking.java b/src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestVanillaBenchmarking.java similarity index 95% rename from src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestFCUStaticBenchmarking.java rename to src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestVanillaBenchmarking.java index efb2330a..10cf6e90 100644 --- a/src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestFCUStaticBenchmarking.java +++ b/src/test/java/org/fogbowcloud/manager/core/plugins/benchmarking/TestVanillaBenchmarking.java @@ -5,7 +5,7 @@ import java.util.Map; import org.fogbowcloud.manager.core.plugins.BenchmarkingPlugin; -import org.fogbowcloud.manager.core.plugins.benchmarking.FCUStaticBenchmarkingPlugin; +import org.fogbowcloud.manager.core.plugins.benchmarking.VanillaBenchmarkingPlugin; import org.fogbowcloud.manager.occi.core.Resource; import org.fogbowcloud.manager.occi.instance.Instance; import org.fogbowcloud.manager.occi.instance.Instance.Link; @@ -14,18 +14,18 @@ import org.junit.Before; import org.junit.Test; -public class TestFCUStaticBenchmarking { +public class TestVanillaBenchmarking { private static final double ACCEPTABLE_ERROR = 0.00; Map instanceAttributes; - FCUStaticBenchmarkingPlugin benchmarking; + VanillaBenchmarkingPlugin benchmarking; @Before public void setUp(){ instanceAttributes = new HashMap(); instanceAttributes.put("occi.compute.memory", "2"); instanceAttributes.put("occi.compute.cores", "2"); - benchmarking = new FCUStaticBenchmarkingPlugin(null); + benchmarking = new VanillaBenchmarkingPlugin(null); } @Test diff --git a/src/test/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/TestVMCatcherStoragePluginTest.java b/src/test/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/TestVMCatcherStoragePluginTest.java new file mode 100644 index 00000000..ad6c4006 --- /dev/null +++ b/src/test/java/org/fogbowcloud/manager/core/plugins/imagestorage/vmcatcher/TestVMCatcherStoragePluginTest.java @@ -0,0 +1,111 @@ +package org.fogbowcloud.manager.core.plugins.imagestorage.vmcatcher; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; +import java.util.concurrent.ExecutorService; + +import org.fogbowcloud.manager.core.CurrentThreadExecutorService; +import org.fogbowcloud.manager.core.plugins.ComputePlugin; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +public class TestVMCatcherStoragePluginTest { + + private static final String IMAGE_LIST_URL = "file://" + new File("").getAbsolutePath() + + "/src/test/resources/imagestorage/vmcatcher/image.list"; + private ExecutorService downloader; + private ComputePlugin computePlugin; + private ShellWrapper shellWrapper; + private Properties properties; + private VMCatcherStoragePlugin plugin; + + @Before + public void setup() { + this.downloader = Mockito.mock(ExecutorService.class); + this.computePlugin = Mockito.mock(ComputePlugin.class); + this.shellWrapper = Mockito.mock(ShellWrapper.class); + this.properties = new Properties(); + this.plugin = new VMCatcherStoragePlugin(properties, + computePlugin, downloader, shellWrapper); + } + + @Test + public void testImageListWithMalformedURL() { + Assert.assertNull(plugin.getLocalId(null, "non-url")); + Mockito.verifyZeroInteractions(downloader); + } + + @Test + public void testImageListWithNotFoundURL() { + Assert.assertNull(plugin.getLocalId(null, "file://path/does/not/exist")); + Mockito.verifyZeroInteractions(downloader); + } + + @Test + public void testImageWithValidURLWithNoIdentifierCesga() { + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "cesga"); + Assert.assertNull(plugin.getLocalId(null, "file://" + new File("").getAbsolutePath() + + "/src/test/resources/imagestorage/vmcatcher/image.list.noidentifier")); + Mockito.verifyZeroInteractions(downloader); + } + + @Test + public void testImageWithValidURLWithNoIdentifierGlance() { + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "glancepush"); + Assert.assertNull(plugin.getLocalId(null, "file://" + new File("").getAbsolutePath() + + "/src/test/resources/imagestorage/vmcatcher/image.list.notitle")); + Mockito.verifyZeroInteractions(downloader); + } + + @Test + public void testImageWithValidURLWithProperIdentifierCesga() throws IOException, InterruptedException { + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "cesga"); + Assert.assertNull(plugin.getLocalId(null, IMAGE_LIST_URL)); + Mockito.verify(computePlugin).getImageId(null, "776690f9-d023-44c6-9923-b66ed853d77b"); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_subscribe", + "--imagelist-newimage-subscribe", "--auto-endorse", "-s", IMAGE_LIST_URL); + Mockito.verify(downloader).execute(Mockito.any(Runnable.class)); + } + + @Test + public void testImageWithValidURLWithProperIdentifierGlance() throws IOException, InterruptedException { + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "glancepush"); + Assert.assertNull(plugin.getLocalId(null, IMAGE_LIST_URL)); + Mockito.verify(computePlugin).getImageId(null, "Scientific_Linux_6.5_Minimal"); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_subscribe", + "--imagelist-newimage-subscribe", "--auto-endorse", "-s", IMAGE_LIST_URL); + Mockito.verify(downloader).execute(Mockito.any(Runnable.class)); + } + + @Test + public void testImageWithValidURLWithProperIdentifierCesgaSameThread() throws IOException, InterruptedException { + setupInSameThread(); + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "cesga"); + Assert.assertNull(plugin.getLocalId(null, IMAGE_LIST_URL)); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_subscribe", "-U"); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_cache"); + } + + @Test + public void testImageWithValidURLWithProperIdentifierGlanceSameThread() throws IOException, InterruptedException { + setupInSameThread(); + properties.put(VMCatcherStoragePlugin.PROP_VMC_PUSH_METHOD, "glancepush"); + Assert.assertNull(plugin.getLocalId(null, IMAGE_LIST_URL)); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_subscribe", "-U"); + Mockito.verify(shellWrapper).execute("sudo", "vmcatcher_cache"); + } + + private void setupInSameThread() { + CurrentThreadExecutorService executor = new CurrentThreadExecutorService(); + this.downloader = Mockito.mock(ExecutorService.class); + this.computePlugin = Mockito.mock(ComputePlugin.class); + this.shellWrapper = Mockito.mock(ShellWrapper.class); + this.properties = new Properties(); + this.plugin = new VMCatcherStoragePlugin(properties, + computePlugin, executor, shellWrapper); + } + +} diff --git a/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/TestPrioritizeRemotePlugin.java b/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/TestPrioritizeRemotePlugin.java new file mode 100644 index 00000000..1c71357a --- /dev/null +++ b/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/TestPrioritizeRemotePlugin.java @@ -0,0 +1,198 @@ +package org.fogbowcloud.manager.core.plugins.prioritization; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Properties; + +import org.fogbowcloud.manager.core.ConfigurationConstants; +import org.fogbowcloud.manager.core.model.DateUtils; +import org.fogbowcloud.manager.core.plugins.AccountingPlugin; +import org.fogbowcloud.manager.core.util.DefaultDataTestHelper; +import org.fogbowcloud.manager.occi.core.Token; +import org.fogbowcloud.manager.occi.request.Request; +import org.fogbowcloud.manager.occi.request.RequestState; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +public class TestPrioritizeRemotePlugin { + + private Properties properties; + private AccountingPlugin accountingPlugin; + + @Before + public void setUp(){ + properties = new Properties(); + properties.put(ConfigurationConstants.XMPP_JID_KEY, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + accountingPlugin = Mockito.mock(AccountingPlugin.class); + } + + @Test + public void testTakeNullForLocalRequest() { + PriotizeRemoteRequestPlugin plugin = new PriotizeRemoteRequestPlugin(properties, accountingPlugin); + + // mocking dateUtils + long now = System.currentTimeMillis(); + DateUtils dateUtils = Mockito.mock(DateUtils.class); + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request servedRequest1 = new Request("id1", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest1.setInstanceId("instanceId1"); + servedRequest1.setState(RequestState.FULFILLED); + servedRequest1.setFulfilledByFederationUser(true); + servedRequest1.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now + 30); + + Request servedRequest2 = new Request("id2", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest2.setInstanceId("instanceId2"); + servedRequest2.setState(RequestState.FULFILLED); + servedRequest2.setFulfilledByFederationUser(true); + servedRequest2.setProvidingMemberId("localMemberId"); + + List requests = new ArrayList(); + requests.add(servedRequest1); + requests.add(servedRequest2); + + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, dateUtils); + + Assert.assertNull(plugin.takeFrom(newRequest, requests)); + } + + @Test + public void testTakeMostRecentServedRequest() { + PriotizeRemoteRequestPlugin plugin = new PriotizeRemoteRequestPlugin(properties, accountingPlugin); + + // mocking dateUtils + long now = System.currentTimeMillis(); + DateUtils dateUtils = Mockito.mock(DateUtils.class); + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request servedRequest1 = new Request("id1", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest1.setInstanceId("instanceId1"); + servedRequest1.setState(RequestState.FULFILLED); + servedRequest1.setFulfilledByFederationUser(true); + servedRequest1.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now + 30); + + Request servedRequest2 = new Request("id2", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest2.setInstanceId("instanceId2"); + servedRequest2.setState(RequestState.FULFILLED); + servedRequest2.setFulfilledByFederationUser(true); + servedRequest2.setProvidingMemberId("localMemberId"); + + List requests = new ArrayList(); + requests.add(servedRequest1); + requests.add(servedRequest2); + + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2", dateUtils); + + // checking if take from most recent request + Assert.assertEquals(servedRequest2, plugin.takeFrom(newRequest, requests)); + } + + @Test + public void testTakeMostRecentLocalRequest() { + PriotizeRemoteRequestPlugin plugin = new PriotizeRemoteRequestPlugin(properties, accountingPlugin); + + // mocking dateUtils + long now = System.currentTimeMillis(); + DateUtils dateUtils = Mockito.mock(DateUtils.class); + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request request1 = new Request("id1", new Token("accessId", "localUserId", null, + new HashMap()), null, null, null, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, dateUtils); + request1.setInstanceId("instanceId1"); + request1.setState(RequestState.FULFILLED); + request1.setFulfilledByFederationUser(true); + request1.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now + 30); + + Request request2 = new Request("id2", new Token("accessId", "localUserId", null, + new HashMap()), null, null, null, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, dateUtils); + request2.setInstanceId("instanceId2"); + request2.setState(RequestState.FULFILLED); + request2.setFulfilledByFederationUser(true); + request2.setProvidingMemberId("localMemberId"); + + List requests = new ArrayList(); + requests.add(request1); + requests.add(request2); + + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2", dateUtils); + + // checking if take from most recent request + Assert.assertEquals(request2, plugin.takeFrom(newRequest, requests)); + } + + @Test + public void testTakeMostRecentAccrossLocalAndServedRequest() { + PriotizeRemoteRequestPlugin plugin = new PriotizeRemoteRequestPlugin(properties, accountingPlugin); + + // mocking dateUtils + long now = System.currentTimeMillis(); + DateUtils dateUtils = Mockito.mock(DateUtils.class); + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request servedRequest1 = new Request("id1", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest1.setInstanceId("instanceId1"); + servedRequest1.setState(RequestState.FULFILLED); + servedRequest1.setFulfilledByFederationUser(true); + servedRequest1.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + now += 30; + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request request2 = new Request("id2", new Token("accessId", "localUserId", null, + new HashMap()), null, null, null, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, dateUtils); + request2.setInstanceId("instanceId2"); + request2.setState(RequestState.FULFILLED); + request2.setFulfilledByFederationUser(true); + request2.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + now += 30; + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request request3 = new Request("id3", new Token("accessId", "localUserId", null, + new HashMap()), null, null, null, true, + DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, dateUtils); + request3.setInstanceId("instanceId3"); + request3.setState(RequestState.FULFILLED); + request3.setFulfilledByFederationUser(true); + request3.setProvidingMemberId("localMemberId"); + + List requests = new ArrayList(); + requests.add(servedRequest1); + requests.add(request2); + requests.add(request3); + + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2", dateUtils); + + // checking if take from most recent request + Assert.assertEquals(request3, plugin.takeFrom(newRequest, requests)); + } +} diff --git a/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/TestNoFPrioritizationPlugin.java b/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/TestNoFPrioritizationPlugin.java index 9bafa7cf..80bc9d6a 100644 --- a/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/TestNoFPrioritizationPlugin.java +++ b/src/test/java/org/fogbowcloud/manager/core/plugins/prioritization/nof/TestNoFPrioritizationPlugin.java @@ -29,6 +29,7 @@ public void setUp(){ properties.put(ConfigurationConstants.XMPP_JID_KEY, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); properties.put("nof_trustworthy", "false"); + properties.put("nof_prioritize_local", "true"); accountingPlugin = Mockito.mock(AccountingPlugin.class); } @@ -39,8 +40,11 @@ public void testServedRequestsNull() { Mockito.when(accountingPlugin.getMembersUsage()).thenReturn( new HashMap()); + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "memberId"); + NoFPrioritizationPlugin nofPlugin = new NoFPrioritizationPlugin(properties, accountingPlugin); - Assert.assertNull(nofPlugin.takeFrom("memberId", null)); + Assert.assertNull(nofPlugin.takeFrom(newRequest, null)); } @Test @@ -49,12 +53,15 @@ public void testEmptyServedRequests() { Mockito.when(accountingPlugin.getMembersUsage()).thenReturn( new HashMap()); + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "memberId"); + NoFPrioritizationPlugin nofPlugin = new NoFPrioritizationPlugin(properties, accountingPlugin); - Assert.assertNull(nofPlugin.takeFrom("memberId", new ArrayList())); + Assert.assertNull(nofPlugin.takeFrom(newRequest, new ArrayList())); } - + @Test - public void testNoServedRequest() { + public void testTakeFromOneServedRequest() { //mocking accounting HashMap membersUsage = new HashMap(); ResourceUsage member1Usage = new ResourceUsage("member1"); @@ -68,36 +75,31 @@ public void testNoServedRequest() { membersUsage.put("member1", member1Usage); membersUsage.put("member2", member2Usage); Mockito.when(accountingPlugin.getMembersUsage()).thenReturn( - membersUsage); + membersUsage); NoFPrioritizationPlugin nofPlugin = new NoFPrioritizationPlugin(properties, accountingPlugin); - Request localRequest1 = new Request("id1", new Token("accessId", "localUserId", null, - new HashMap()), null, null, null, true, "localMemberId"); - localRequest1.setInstanceId("instanceId1"); - localRequest1.setState(RequestState.FULFILLED); - localRequest1.setProvidingMemberId("localMemberId"); - - Request localRequest2 = new Request("id2", new Token("accessId", "localUserId", null, - new HashMap()), null, null, null, true, "localMemberId"); - localRequest2.setInstanceId("instanceId2"); - localRequest2.setState(RequestState.FULFILLED); - localRequest2.setProvidingMemberId("localMemberId"); + Request servedRequest = new Request("id", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1"); + servedRequest.setInstanceId("instanceId"); + servedRequest.setState(RequestState.FULFILLED); + servedRequest.setProvidingMemberId("localMemberId"); List requests = new ArrayList(); - requests.add(localRequest1); - requests.add(localRequest2); + requests.add(servedRequest); - // check if there is no instance to take from because there is no served request - Assert.assertNull(nofPlugin.takeFrom("member2", requests)); + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2"); + + Assert.assertEquals(servedRequest, nofPlugin.takeFrom(newRequest, requests)); } @Test - public void testTakeFromOneServedRequest() { + public void testNoTakeFromBecauseDebtIsTheSame() { //mocking accounting HashMap membersUsage = new HashMap(); ResourceUsage member1Usage = new ResourceUsage("member1"); - member1Usage.addConsumption(20); + member1Usage.addConsumption(30); member1Usage.addDonation(10); ResourceUsage member2Usage = new ResourceUsage("member2"); @@ -120,15 +122,18 @@ public void testTakeFromOneServedRequest() { List requests = new ArrayList(); requests.add(servedRequest); - Assert.assertEquals(servedRequest, nofPlugin.takeFrom("member2", requests)); + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2"); + + Assert.assertNull(nofPlugin.takeFrom(newRequest, requests)); } @Test - public void testNoTakeFromBecauseDebtIsTheSame() { + public void testTakeFromMostRecentServedRequest() { //mocking accounting HashMap membersUsage = new HashMap(); ResourceUsage member1Usage = new ResourceUsage("member1"); - member1Usage.addConsumption(30); + member1Usage.addConsumption(20); member1Usage.addDonation(10); ResourceUsage member2Usage = new ResourceUsage("member2"); @@ -142,20 +147,39 @@ public void testNoTakeFromBecauseDebtIsTheSame() { NoFPrioritizationPlugin nofPlugin = new NoFPrioritizationPlugin(properties, accountingPlugin); - Request servedRequest = new Request("id", new Token("accessId", "remoteUserId", null, - new HashMap()), null, null, null, false, "member1"); - servedRequest.setInstanceId("instanceId"); - servedRequest.setState(RequestState.FULFILLED); - servedRequest.setProvidingMemberId("localMemberId"); + // mocking dateUtils + long now = System.currentTimeMillis(); + DateUtils dateUtils = Mockito.mock(DateUtils.class); + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now); + + Request servedRequest1 = new Request("id1", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest1.setInstanceId("instanceId1"); + servedRequest1.setState(RequestState.FULFILLED); + servedRequest1.setProvidingMemberId("localMemberId"); + + // mocking dateUtils + Mockito.when(dateUtils.currentTimeMillis()).thenReturn(now + 30); + + Request servedRequest2 = new Request("id2", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1", dateUtils); + servedRequest2.setInstanceId("instanceId2"); + servedRequest2.setState(RequestState.FULFILLED); + servedRequest2.setProvidingMemberId("localMemberId"); List requests = new ArrayList(); - requests.add(servedRequest); + requests.add(servedRequest1); + requests.add(servedRequest2); + + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2"); - Assert.assertNull(nofPlugin.takeFrom("member2", requests)); + // checking if take from most recent request + Assert.assertEquals(servedRequest2, nofPlugin.takeFrom(newRequest, requests)); } @Test - public void testTakeFromMostRecentServedRequest() { + public void testMoreThanOneTakeFromServedRequest() { //mocking accounting HashMap membersUsage = new HashMap(); ResourceUsage member1Usage = new ResourceUsage("member1"); @@ -197,12 +221,55 @@ public void testTakeFromMostRecentServedRequest() { requests.add(servedRequest1); requests.add(servedRequest2); + Request newRequest = new Request("newID", new Token("newAccessId", "newRemoteUserId", null, + new HashMap()), null, null, null, false, "member2"); + // checking if take from most recent request - Assert.assertEquals(servedRequest2, nofPlugin.takeFrom("member2", requests)); + Assert.assertEquals(servedRequest2, nofPlugin.takeFrom(newRequest, requests)); + + requests.remove(servedRequest2); + Assert.assertEquals(servedRequest1, nofPlugin.takeFrom(newRequest, requests)); + + requests.remove(servedRequest1); + Assert.assertNull(nofPlugin.takeFrom(newRequest, requests)); } @Test - public void testMoreThanOneTakeFromServedRequest() { + public void testPrioritizeLocalRequest() { + //mocking accounting + HashMap membersUsage = new HashMap(); + ResourceUsage member1Usage = new ResourceUsage("member1"); + member1Usage.addConsumption(20); + member1Usage.addDonation(10); + + ResourceUsage member2Usage = new ResourceUsage("member2"); + member2Usage.addConsumption(30); + member2Usage.addDonation(10); + + membersUsage.put("member1", member1Usage); + membersUsage.put("member2", member2Usage); + Mockito.when(accountingPlugin.getMembersUsage()).thenReturn( + membersUsage); + + NoFPrioritizationPlugin nofPlugin = new NoFPrioritizationPlugin(properties, accountingPlugin); + + Request servedRequest = new Request("id", new Token("accessId", "remoteUserId", null, + new HashMap()), null, null, null, false, "member1"); + servedRequest.setInstanceId("instanceId"); + servedRequest.setState(RequestState.FULFILLED); + servedRequest.setProvidingMemberId("localMemberId"); + + List requests = new ArrayList(); + requests.add(servedRequest); + + Request newRequest = new Request("newID", new Token("newAccessId", "newLocalUserId", null, + new HashMap()), null, null, null, true, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + + Assert.assertEquals(servedRequest, nofPlugin.takeFrom(newRequest, requests)); + } + + @Test + public void testPrioritizeLocalRequestWithThanOneServedRequest() { //mocking accounting HashMap membersUsage = new HashMap(); ResourceUsage member1Usage = new ResourceUsage("member1"); @@ -244,13 +311,16 @@ public void testMoreThanOneTakeFromServedRequest() { requests.add(servedRequest1); requests.add(servedRequest2); + Request newRequest = new Request("newID", new Token("newAccessId", "newLocalUserId", null, + new HashMap()), null, null, null, true, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); + // checking if take from most recent request - Assert.assertEquals(servedRequest2, nofPlugin.takeFrom("member2", requests)); + Assert.assertEquals(servedRequest2, nofPlugin.takeFrom(newRequest, requests)); requests.remove(servedRequest2); - Assert.assertEquals(servedRequest1, nofPlugin.takeFrom("member2", requests)); + Assert.assertEquals(servedRequest1, nofPlugin.takeFrom(newRequest, requests)); requests.remove(servedRequest1); - Assert.assertNull(nofPlugin.takeFrom("member2", requests)); + Assert.assertNull(nofPlugin.takeFrom(newRequest, requests)); } } diff --git a/src/test/java/org/fogbowcloud/manager/core/util/DefaultDataTestHelper.java b/src/test/java/org/fogbowcloud/manager/core/util/DefaultDataTestHelper.java index a79ac82a..f62ac6b3 100644 --- a/src/test/java/org/fogbowcloud/manager/core/util/DefaultDataTestHelper.java +++ b/src/test/java/org/fogbowcloud/manager/core/util/DefaultDataTestHelper.java @@ -20,6 +20,7 @@ public class DefaultDataTestHelper { //manager controller data public static final String CONFIG_PATH = "src/test/resources/manager.conf.test"; + public static final String LOCAL_MANAGER_SSH_PUBLIC_KEY_PATH = "src/test/resources/server.id_rsa.pub"; //time data public static final Long SCHEDULER_PERIOD = 500L; diff --git a/src/test/java/org/fogbowcloud/manager/core/util/ManagerTestHelper.java b/src/test/java/org/fogbowcloud/manager/core/util/ManagerTestHelper.java index 462ec277..deed353a 100644 --- a/src/test/java/org/fogbowcloud/manager/core/util/ManagerTestHelper.java +++ b/src/test/java/org/fogbowcloud/manager/core/util/ManagerTestHelper.java @@ -7,9 +7,9 @@ import java.util.Date; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -24,7 +24,6 @@ import org.fogbowcloud.manager.core.FederationMemberPicker; import org.fogbowcloud.manager.core.ManagerController; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.core.plugins.AccountingPlugin; import org.fogbowcloud.manager.core.plugins.AuthorizationPlugin; @@ -83,11 +82,8 @@ public ManagerTestHelper() { } public ResourcesInfo getResources() throws CertificateException, IOException { - List flavours = new LinkedList(); - flavours.add(new Flavor("small", "cpu", "mem", 2)); - flavours.add(new Flavor("small", "cpu", "mem", 3)); - ResourcesInfo resources = new ResourcesInfo("abc", "value1", "value2", "value3", "value4", - flavours); + ResourcesInfo resources = new ResourcesInfo("abc", "cpu-idle", "cpu-in-use", "mem-idle", + "mem-in-use", "instances-idle", "instances-in-use"); return resources; } @@ -102,18 +98,14 @@ public IQ createWhoIsAliveResponse(ArrayList aliveIds, IQ iq) statusEl.addElement("cpu-idle").setText(rendezvousItem.getResourcesInfo().getCpuIdle()); statusEl.addElement("cpu-inuse").setText( rendezvousItem.getResourcesInfo().getCpuInUse()); - statusEl.addElement("mem-idle").setText(rendezvousItem.getResourcesInfo().getMemIdle()); + statusEl.addElement("mem-idle").setText( + rendezvousItem.getResourcesInfo().getMemIdle()); statusEl.addElement("mem-inuse").setText( rendezvousItem.getResourcesInfo().getMemInUse()); - - List flavours = rendezvousItem.getResourcesInfo().getFlavors(); - for (Flavor f : flavours) { - Element flavorElement = statusEl.addElement("flavor"); - flavorElement.addElement("name").setText(f.getName()); - flavorElement.addElement("cpu").setText(f.getCpu()); - flavorElement.addElement("mem").setText(f.getMem()); - flavorElement.addElement("capacity").setText(f.getCapacity().toString()); - } + statusEl.addElement("instances-idle").setText( + rendezvousItem.getResourcesInfo().getInstancesIdle()); + statusEl.addElement("instances-inuse").setText( + rendezvousItem.getResourcesInfo().getInstancesInUse()); statusEl.addElement("cert"); statusEl.addElement("updated").setText( String.valueOf(rendezvousItem.getFormattedTime())); @@ -194,9 +186,9 @@ public ManagerXmppComponent initializeXMPPManagerComponent(boolean init) throws properties.put(ConfigurationConstants.FEDERATION_USER_PASS_KEY, "fogbow"); properties.put(ConfigurationConstants.FEDERATION_USER_TENANT_NAME_KEY, "fogbow"); properties.put(ConfigurationConstants.XMPP_JID_KEY, "manager.test.com"); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); properties.put(ConfigurationConstants.MAX_WHOISALIVE_MANAGER_COUNT, MAX_WHOISALIVE_MANAGER_COUNT); @@ -301,20 +293,11 @@ public List getItemsFromIQ(Packet response) throws Certificate String cpuInUse = statusEl.element("cpu-inuse").getText(); String memIdle = statusEl.element("mem-idle").getText(); String memInUse = statusEl.element("mem-inuse").getText(); - List flavoursList = new LinkedList(); - Iterator flavourIterator = itemEl.elementIterator("flavor"); - while (flavourIterator.hasNext()) { - Element flavour = itemIterator.next(); - String name = flavour.element("name").getText(); - String cpu = flavour.element("cpu").getText(); - String mem = flavour.element("mem").getText(); - int capacity = Integer.parseInt(flavour.element("capacity").getText()); - Flavor flavor = new Flavor(name, cpu, mem, capacity); - flavoursList.add(flavor); - } + String instancesIdle = statusEl.element("instances-idle").getText(); + String instancesInUse = statusEl.element("instances-inuse").getText(); ResourcesInfo resources = new ResourcesInfo(id.getValue(), cpuIdle, cpuInUse, memIdle, - memInUse, flavoursList); + memInUse, instancesIdle, instancesInUse); FederationMember item = new FederationMember(resources); aliveItems.add(item); } @@ -335,8 +318,12 @@ public Properties getProperties(String path) throws IOException { return properties; } - @SuppressWarnings("unchecked") public ManagerController createDefaultManagerController() { + return createDefaultManagerController(null); + } + + @SuppressWarnings("unchecked") + public ManagerController createDefaultManagerController(Map extraProperties) { Properties properties = new Properties(); properties.put(ConfigurationConstants.XMPP_JID_KEY, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); @@ -350,9 +337,9 @@ public ManagerController createDefaultManagerController() { DefaultDataTestHelper.SCHEDULER_PERIOD.toString()); properties.put(ConfigurationConstants.INSTANCE_MONITORING_PERIOD_KEY, Long.toString(DefaultDataTestHelper.LONG_TIME)); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); properties.put(ConfigurationConstants.PREFIX_FLAVORS + "small", VALUE_FLAVOR_SMALL); properties.put(ConfigurationConstants.PREFIX_FLAVORS + "medium", VALUE_FLAVOR_MEDIUM); @@ -360,6 +347,13 @@ public ManagerController createDefaultManagerController() { properties.put(ConfigurationConstants.SERVED_REQUEST_MONITORING_PERIOD_KEY, String.valueOf(DefaultDataTestHelper.SERVED_REQUEST_MONITORING_PERIOD)); properties.put(ConfigurationConstants.GREEN_SITTER_JID, DefaultDataTestHelper.GREEN_SITTER_JID); + + if (extraProperties != null) { + for (Entry entry : extraProperties.entrySet()) { + properties.put(entry.getKey(), entry.getValue()); + } + } + this.executorService = Mockito.mock(ScheduledExecutorService.class); ManagerController managerController = new ManagerController(properties, executorService); @@ -372,8 +366,7 @@ public ManagerController createDefaultManagerController() { new OCCIException(ErrorType.QUOTA_EXCEEDED, ResponseConstants.QUOTA_EXCEEDED_FOR_INSTANCES)); Mockito.when(computePlugin.getResourcesInfo(Mockito.any(Token.class))).thenReturn( - new ResourcesInfo(LOCAL_MANAGER_COMPONENT_URL, - "", "", "", "", new LinkedList())); + new ResourcesInfo(LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", "", "")); Mockito.when(computePlugin.getInstances(Mockito.any(Token.class))).thenReturn( new ArrayList()); @@ -398,7 +391,7 @@ public ManagerController createDefaultManagerController() { memberPickerPlugin = Mockito.mock(FederationMemberPicker.class); Mockito.when(memberPickerPlugin.pick(Mockito.any(List.class))).thenReturn( new FederationMember(new ResourcesInfo( - DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL, "", "", "", null))); + DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL, "", "", "", "", ""))); // mocking benchmark executor ExecutorService benchmarkExecutor = new CurrentThreadExecutorService(); diff --git a/src/test/java/org/fogbowcloud/manager/occi/TestBypassCompute.java b/src/test/java/org/fogbowcloud/manager/occi/TestBypassCompute.java index 2defe7ae..951912ce 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/TestBypassCompute.java +++ b/src/test/java/org/fogbowcloud/manager/occi/TestBypassCompute.java @@ -80,9 +80,9 @@ private void setup(List requests) throws Exception { properties.put(OpenStackConfigurationConstants.COMPUTE_OCCI_FLAVOR_LARGE_KEY, OCCIComputeApplication.MEDIUM_FLAVOR_TERM); properties.put(OpenStackConfigurationConstants.COMPUTE_OCCI_IMAGE_PREFIX + PluginHelper.LINUX_X86_TERM, PluginHelper.CIRROS_IMAGE_TERM); properties.put(ConfigurationConstants.SCHEDULER_PERIOD_KEY, LITTLE_SCHEDULE_TIME); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); defaultToken = new Token(PluginHelper.ACCESS_ID, PluginHelper.USERNAME, diff --git a/src/test/java/org/fogbowcloud/manager/occi/TestMemberServerResource.java b/src/test/java/org/fogbowcloud/manager/occi/TestMemberServerResource.java index 8e9d9f29..332c8f99 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/TestMemberServerResource.java +++ b/src/test/java/org/fogbowcloud/manager/occi/TestMemberServerResource.java @@ -12,7 +12,6 @@ import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.core.plugins.AccountingPlugin; import org.fogbowcloud.manager.core.plugins.AuthorizationPlugin; @@ -30,8 +29,6 @@ public class TestMemberServerResource { - private final String FLAVOUR_1 = "flavour1"; - private final String FLAVOUR_2 = "flavour1"; private final String ID_RESOURCEINFO1 = "id1"; private final String ID_RESOURCEINFO2 = "id2"; @@ -46,7 +43,7 @@ public void setup() throws Exception { this.computePlugin = Mockito.mock(ComputePlugin.class); Mockito.when(computePlugin.getResourcesInfo(Mockito.any(Token.class))).thenReturn( new ResourcesInfo(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, - "", "", "", "", new LinkedList())); + "", "", "", "", "", "")); this.identityPlugin = Mockito.mock(IdentityPlugin.class); this.accoutingPlugin = Mockito.mock(AccountingPlugin.class); this.authorizationPlugin = Mockito.mock(AuthorizationPlugin.class); @@ -61,13 +58,10 @@ public void tearDown() throws Exception { @Test public void testGetMember() throws Exception { List federationMembers = new ArrayList(); - List flavours = new ArrayList(); - flavours.add(new Flavor(FLAVOUR_1, "3", "135", 2)); - flavours.add(new Flavor(FLAVOUR_2, "3", "135", 2)); ResourcesInfo resourcesInfo = new ResourcesInfo(ID_RESOURCEINFO1, "2", "1", "100", "35", - flavours); + "", ""); ResourcesInfo resourcesInfo2 = new ResourcesInfo(ID_RESOURCEINFO2, "2", "1", "100", "35", - null); + "", ""); federationMembers.add(new FederationMember(resourcesInfo)); federationMembers.add(new FederationMember(resourcesInfo)); federationMembers.add(new FederationMember(resourcesInfo2)); @@ -84,8 +78,6 @@ public void testGetMember() throws Exception { String.valueOf(Charsets.UTF_8)); Assert.assertTrue(checkResponse(responseStr)); - Assert.assertTrue(responseStr.contains(FLAVOUR_1)); - Assert.assertTrue(responseStr.contains(FLAVOUR_2)); Assert.assertTrue(responseStr.contains(ID_RESOURCEINFO1)); Assert.assertTrue(responseStr.contains(ID_RESOURCEINFO2)); Assert.assertTrue(responseStr.contains(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL)); diff --git a/src/test/java/org/fogbowcloud/manager/occi/TestOCCIApplication.java b/src/test/java/org/fogbowcloud/manager/occi/TestOCCIApplication.java index 174085b8..b09cf0b6 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/TestOCCIApplication.java +++ b/src/test/java/org/fogbowcloud/manager/occi/TestOCCIApplication.java @@ -52,9 +52,9 @@ public void setUp() { properties.put("scheduler_period", SCHEDULER_PERIOD.toString()); properties.put(ConfigurationConstants.XMPP_JID_KEY, DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); ScheduledExecutorService executor = Mockito.mock(ScheduledExecutorService.class); diff --git a/src/test/java/org/fogbowcloud/manager/occi/TestUsageServerResource.java b/src/test/java/org/fogbowcloud/manager/occi/TestUsageServerResource.java index d2c960e1..49bef267 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/TestUsageServerResource.java +++ b/src/test/java/org/fogbowcloud/manager/occi/TestUsageServerResource.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -13,7 +12,6 @@ import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.core.plugins.AccountingPlugin; import org.fogbowcloud.manager.core.plugins.AuthorizationPlugin; @@ -50,15 +48,15 @@ public void setup() throws Exception { this.computePlugin = Mockito.mock(ComputePlugin.class); Mockito.when(computePlugin.getResourcesInfo(Mockito.any(Token.class))).thenReturn( new ResourcesInfo(DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, - "", "", "", "", new LinkedList())); + "", "", "", "", "", "")); this.identityPlugin = Mockito.mock(IdentityPlugin.class); this.accountingPlugin = Mockito.mock(AccountingPlugin.class); this.authorizationPlugin = Mockito.mock(AuthorizationPlugin.class); ResourcesInfo resourcesInfo = new ResourcesInfo(ID_RESOURCEINFO1, "", "", "", "", - new ArrayList()); + "", ""); ResourcesInfo resourcesInfo2 = new ResourcesInfo(ID_RESOURCEINFO2, "", "", "", "", - new ArrayList()); + "", ""); federationMembers.add(new FederationMember(resourcesInfo)); federationMembers.add(new FederationMember(resourcesInfo2)); diff --git a/src/test/java/org/fogbowcloud/manager/occi/plugins/opennebula/TestComputeOpenNebula.java b/src/test/java/org/fogbowcloud/manager/occi/plugins/opennebula/TestComputeOpenNebula.java index 264445dd..f6cee5f0 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/plugins/opennebula/TestComputeOpenNebula.java +++ b/src/test/java/org/fogbowcloud/manager/occi/plugins/opennebula/TestComputeOpenNebula.java @@ -600,11 +600,8 @@ public void testGetResourcesInfo() { Assert.assertEquals("0.0", resourcesInfo.getCpuInUse()); Assert.assertEquals("5120.0", resourcesInfo.getMemIdle()); Assert.assertEquals("0.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 10)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 5)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 2)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals("10", resourcesInfo.getInstancesIdle()); + Assert.assertEquals("0", resourcesInfo.getInstancesInUse()); } @Test @@ -660,11 +657,8 @@ public void testGetResourcesInfoWithAllUserQuotaSmallerThanGroupQuota() { Assert.assertEquals("0.0", resourcesInfo.getCpuInUse()); Assert.assertEquals("4096.0", resourcesInfo.getMemIdle()); Assert.assertEquals("0.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 5 / 1)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 5 / 2)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 5 / 4)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals("5", resourcesInfo.getInstancesIdle()); + Assert.assertEquals("0", resourcesInfo.getInstancesInUse()); } @Test @@ -720,11 +714,8 @@ public void testGetResourcesInfoWithAllGroupQuotaSmallerThanUserQuota() { Assert.assertEquals("0.0", resourcesInfo.getCpuInUse()); Assert.assertEquals("4096.0", resourcesInfo.getMemIdle()); Assert.assertEquals("0.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 5 / 1)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 5 / 2)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 5 / 4)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals("5", resourcesInfo.getInstancesIdle()); + Assert.assertEquals("0", resourcesInfo.getInstancesInUse()); } @Test @@ -780,11 +771,8 @@ public void testGetResourcesInfoWithSomeUserQuotaSmallerThanGroup() { Assert.assertEquals("0.0", resourcesInfo.getCpuInUse()); Assert.assertEquals("4096.0", resourcesInfo.getMemIdle()); Assert.assertEquals("0.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 5 / 1)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 5 / 2)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 5 / 4)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals("10", resourcesInfo.getInstancesIdle()); + Assert.assertEquals("0", resourcesInfo.getInstancesInUse()); } @Test @@ -841,11 +829,8 @@ public void testGetResourcesInfoWithSomeUserQuotaSmallerThanGroupAndUsed() { Assert.assertEquals("2944.0", resourcesInfo.getMemIdle()); // 4096 - // 1152 Assert.assertEquals("1152.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 3 / 1)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 3 / 2)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 3 / 4)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals("7", resourcesInfo.getInstancesIdle()); + Assert.assertEquals("3", resourcesInfo.getInstancesInUse()); } @Test @@ -908,15 +893,7 @@ public void testGetResourcesInfoWithValueDefaultOfQuota() { String memIdleStr = String.valueOf(memIdle); Assert.assertEquals(memIdleStr, resourcesInfo.getMemIdle()); Assert.assertEquals("1024.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, smallCpu, smallMem, calculateCapacity( - cpuIdle, memIdle, smallCpu, smallMem, instanceIdle))); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, mediumCpu, mediumMem, - calculateCapacity(cpuIdle, memIdle, mediumCpu, mediumMem, instanceIdle))); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, largeCpu, largeMem, calculateCapacity( - cpuIdle, memIdle, largeCpu, largeMem, instanceIdle))); - - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals(String.valueOf(instanceIdle), resourcesInfo.getInstancesIdle()); } @Test @@ -976,21 +953,9 @@ public void testGetResourcesInfoWithValueUnlimitedOfQuota() { String memIdleStr = String.valueOf(memIdle); Assert.assertEquals(memIdleStr, resourcesInfo.getMemIdle()); Assert.assertEquals("1024.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, smallCpu, smallMem, calculateCapacity( - cpuIdle, memIdle, smallCpu, smallMem, instanceIdle))); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, mediumCpu, mediumMem, - calculateCapacity(cpuIdle, memIdle, mediumCpu, mediumMem, instanceIdle))); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, largeCpu, largeMem, calculateCapacity( - cpuIdle, memIdle, largeCpu, largeMem, instanceIdle))); - - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); + Assert.assertEquals(String.valueOf(instanceIdle), resourcesInfo.getInstancesIdle()); } - private int calculateCapacity(double cpuIdle, double memIdle, String cpuFlavor, String memFlavor, int instancesIdle) { - return Math.min((int) Math.min(cpuIdle / Double.parseDouble(cpuFlavor), memIdle / Double.parseDouble(memFlavor)), (int) instancesIdle); - } - @Test public void testGetResourcesInfoWithUsed() { // mocking opennebula structures @@ -1031,11 +996,6 @@ public void testGetResourcesInfoWithUsed() { Assert.assertEquals("2.0", resourcesInfo.getCpuInUse()); Assert.assertEquals("4864.0", resourcesInfo.getMemIdle()); Assert.assertEquals("256.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", 8)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", 4)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", 2)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); } @Test @@ -1087,14 +1047,6 @@ public void testGetResourcesInfoWithoutQuota() { Assert.assertEquals(OpenNebulaComputePlugin.DEFAULT_RESOURCE_MAX_VALUE, Double.parseDouble(resourcesInfo.getMemIdle()), 0.0001); Assert.assertEquals("0.0", resourcesInfo.getMemInUse()); - List flavors = new ArrayList(); - flavors.add(new Flavor(RequestConstants.SMALL_TERM, "1.0", "128.0", - OpenNebulaComputePlugin.DEFAULT_RESOURCE_MAX_VALUE / 128)); - flavors.add(new Flavor(RequestConstants.MEDIUM_TERM, "2.0", "256.0", - OpenNebulaComputePlugin.DEFAULT_RESOURCE_MAX_VALUE / 256)); - flavors.add(new Flavor(RequestConstants.LARGE_TERM, "4.0", "512.0", - OpenNebulaComputePlugin.DEFAULT_RESOURCE_MAX_VALUE / 512)); - Assert.assertEquals(flavors, resourcesInfo.getFlavors()); } @Test diff --git a/src/test/java/org/fogbowcloud/manager/occi/plugins/openstack/TestNovaV2ComputeOpenStack.java b/src/test/java/org/fogbowcloud/manager/occi/plugins/openstack/TestNovaV2ComputeOpenStack.java index 2df89d08..2e29d688 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/plugins/openstack/TestNovaV2ComputeOpenStack.java +++ b/src/test/java/org/fogbowcloud/manager/occi/plugins/openstack/TestNovaV2ComputeOpenStack.java @@ -19,7 +19,6 @@ import org.apache.http.message.BasicStatusLine; import org.fogbowcloud.manager.core.RequirementsHelper; import org.fogbowcloud.manager.core.model.Flavor; -import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.core.plugins.openstack.KeystoneIdentityPlugin; import org.fogbowcloud.manager.core.plugins.openstack.OpenStackConfigurationConstants; import org.fogbowcloud.manager.core.plugins.openstack.OpenStackNovaV2ComputePlugin; @@ -65,7 +64,7 @@ public void setUp() throws Exception { flavors.add(flavorSmall); flavors.add(new Flavor("medium", "2", "2000", "20")); flavors.add(new Flavor("big", "4", "4000", "40")); - novaV2ComputeOpenStack.setFlavors(flavors ); + novaV2ComputeOpenStack.setFlavors(flavors); HashMap tokenAtt = new HashMap(); tokenAtt.put(KeystoneIdentityPlugin.TENANT_ID, "tenantid"); @@ -258,16 +257,6 @@ public void testRemoveInstances(){ Assert.assertEquals(0, novaV2ComputeOpenStack.getInstances(defaultToken).size()); } - @Test - public void testCapacity() { - ResourcesInfo resourcesInfo = novaV2ComputeOpenStack.getResourcesInfo(defaultToken); - List flavors = resourcesInfo.getFlavors(); - // Limited by instance count - Assert.assertEquals(2, (int) flavors.get(0).getCapacity()); - Assert.assertEquals(2, (int) flavors.get(1).getCapacity()); - Assert.assertEquals(2, (int) flavors.get(2).getCapacity()); - } - @Test public void testUpdateFlavor() throws HttpException, IOException { HttpClient client = Mockito.mock(HttpClient.class); diff --git a/src/test/java/org/fogbowcloud/manager/occi/plugins/validators/TestWhitelistMemberValidator.java b/src/test/java/org/fogbowcloud/manager/occi/plugins/validators/TestWhitelistMemberValidator.java index 0ffa06d1..de248c3d 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/plugins/validators/TestWhitelistMemberValidator.java +++ b/src/test/java/org/fogbowcloud/manager/occi/plugins/validators/TestWhitelistMemberValidator.java @@ -27,26 +27,26 @@ public void setup() { @Test public void testCanDonateTo() throws Exception { Assert.assertTrue(memberValidator.canDonateTo( - new FederationMember(new ResourcesInfo("donate1", "", "", "", "", null)), + new FederationMember(new ResourcesInfo("donate1", "", "", "", "", "", "")), null)); } @Test public void testCantDonateTo() throws Exception { Assert.assertFalse(memberValidator.canDonateTo( - new FederationMember(new ResourcesInfo("donate4", "", "", "", "", null)), + new FederationMember(new ResourcesInfo("donate4", "", "", "", "", "", "")), null)); } @Test public void testCanReceiveFrom() throws Exception { Assert.assertTrue(memberValidator.canReceiveFrom( - new FederationMember(new ResourcesInfo("receive1", "", "", "", "", null)))); + new FederationMember(new ResourcesInfo("receive1", "", "", "", "", "", "")))); } @Test public void testCantReceiveFrom() throws Exception { Assert.assertFalse(memberValidator.canReceiveFrom( - new FederationMember(new ResourcesInfo("receive4", "", "", "", "", null)))); + new FederationMember(new ResourcesInfo("receive4", "", "", "", "", "", "")))); } } diff --git a/src/test/java/org/fogbowcloud/manager/occi/util/OCCITestHelper.java b/src/test/java/org/fogbowcloud/manager/occi/util/OCCITestHelper.java index 8a47906d..f402f658 100644 --- a/src/test/java/org/fogbowcloud/manager/occi/util/OCCITestHelper.java +++ b/src/test/java/org/fogbowcloud/manager/occi/util/OCCITestHelper.java @@ -71,9 +71,9 @@ public void initializeComponentExecutorSameThread(ComputePlugin computePlugin, Properties properties = new Properties(); properties.put(ConfigurationConstants.XMPP_JID_KEY, MEMBER_ID); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); properties.put(ConfigurationConstants.PREFIX_FLAVORS + FOGBOW_SMALL_IMAGE, "{cpu=1,mem=100}"); @@ -89,9 +89,8 @@ public Future answer(InvocationOnMock invocation) } }); - ResourceRepository.init(properties); - ManagerController facade = new ManagerController(properties, executor); + ResourceRepository.init(properties); facade.setComputePlugin(computePlugin); facade.setAuthorizationPlugin(authorizationPlugin); facade.setLocalIdentityPlugin(identityPlugin); @@ -108,9 +107,9 @@ public void initializeComponent(ComputePlugin computePlugin, IdentityPlugin iden component.getServers().add(Protocol.HTTP, ENDPOINT_PORT); Properties properties = new Properties(); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); properties.put(ConfigurationConstants.PREFIX_FLAVORS + FOGBOW_SMALL_IMAGE, "{cpu=1,mem=100}"); @@ -137,9 +136,9 @@ public void initializeComponentCompute(ComputePlugin computePlugin, Properties properties = new Properties(); properties.put(ConfigurationConstants.XMPP_JID_KEY, MEMBER_ID); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); ManagerController facade = new ManagerController(properties); facade.setComputePlugin(computePlugin); diff --git a/src/test/java/org/fogbowcloud/manager/xmpp/TestFederationMember.java b/src/test/java/org/fogbowcloud/manager/xmpp/TestFederationMember.java index 0963f701..4a60a50c 100644 --- a/src/test/java/org/fogbowcloud/manager/xmpp/TestFederationMember.java +++ b/src/test/java/org/fogbowcloud/manager/xmpp/TestFederationMember.java @@ -5,10 +5,8 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.LinkedList; import org.fogbowcloud.manager.core.model.FederationMember; -import org.fogbowcloud.manager.core.model.Flavor; import org.fogbowcloud.manager.core.model.ResourcesInfo; import org.fogbowcloud.manager.core.util.ManagerTestHelper; import org.junit.Assert; @@ -35,25 +33,25 @@ public void testInvalidResources() { @Test(expected = IllegalArgumentException.class) public void testNullResourcesCpuIdle() throws CertificateException, IOException { new ResourcesInfo("id", null, - "cpuInUse", "memIdle", "memInUse", new LinkedList()); + "cpuInUse", "memIdle", "memInUse", "", ""); } @Test(expected = IllegalArgumentException.class) public void testNullResourcesCpuInUse() throws CertificateException, IOException { new ResourcesInfo("id", "CpuIdle", - null, "memIdle", "memInUse", new LinkedList()); + null, "memIdle", "memInUse", "", ""); } @Test(expected = IllegalArgumentException.class) public void testNullResourcesMemIdle() throws CertificateException, IOException { new ResourcesInfo("id", "CpuIdle", - "cpuInUse", null, "memInUse", new LinkedList()); + "cpuInUse", null, "memInUse", "", ""); } @Test(expected = IllegalArgumentException.class) public void testNullResourcesMemInUse() throws CertificateException, IOException { new ResourcesInfo("id", "CpuIdle", - "cpuInUse", "memIdle", null, new LinkedList()); + "cpuInUse", "memIdle", null, "", ""); } @Test diff --git a/src/test/java/org/fogbowcloud/manager/xmpp/TestIAmAlive.java b/src/test/java/org/fogbowcloud/manager/xmpp/TestIAmAlive.java index 1e51ef7d..6501bf36 100644 --- a/src/test/java/org/fogbowcloud/manager/xmpp/TestIAmAlive.java +++ b/src/test/java/org/fogbowcloud/manager/xmpp/TestIAmAlive.java @@ -79,6 +79,9 @@ public boolean accept(Packet packet) { String cpuInUse = iqelement.element("cpu-inuse").getText(); String memIdle = iqelement.element("mem-idle").getText(); String memInUse = iqelement.element("mem-inuse").getText(); + String instancesIdle = iqelement.element("instances-idle").getText(); + String instancesInUse = iqelement.element("instances-inuse").getText(); + Assert.assertEquals(cpuIdle, managerTestHelper.getResources() .getCpuIdle()); Assert.assertEquals(cpuInUse, managerTestHelper.getResources() @@ -87,6 +90,10 @@ public boolean accept(Packet packet) { .getMemIdle()); Assert.assertEquals(memInUse, managerTestHelper.getResources() .getMemInUse()); + Assert.assertEquals(instancesIdle, managerTestHelper.getResources() + .getInstancesIdle()); + Assert.assertEquals(instancesInUse, managerTestHelper.getResources() + .getInstancesInUse()); xmppClient.disconnect(); } diff --git a/src/test/java/org/fogbowcloud/manager/xmpp/TestIsInstanceBeenUsed.java b/src/test/java/org/fogbowcloud/manager/xmpp/TestIsInstanceBeenUsed.java index 01bf86dd..e964c52e 100644 --- a/src/test/java/org/fogbowcloud/manager/xmpp/TestIsInstanceBeenUsed.java +++ b/src/test/java/org/fogbowcloud/manager/xmpp/TestIsInstanceBeenUsed.java @@ -136,9 +136,9 @@ private ManagerController createManagerController() { properties.put(ConfigurationConstants.FEDERATION_USER_PASS_KEY, "fogbow"); properties.put(ConfigurationConstants.FEDERATION_USER_TENANT_NAME_KEY, "fogbow"); properties.put(ConfigurationConstants.XMPP_JID_KEY, "manager.test.com"); - properties.put(ConfigurationConstants.SSH_PRIVATE_HOST_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_PRIVATE_HOST_KEY, DefaultDataTestHelper.SERVER_HOST); - properties.put(ConfigurationConstants.SSH_HOST_HTTP_PORT_KEY, + properties.put(ConfigurationConstants.TUNNEL_SSH_HOST_HTTP_PORT_KEY, String.valueOf(DefaultDataTestHelper.TOKEN_SERVER_HTTP_PORT)); properties.put(ConfigurationConstants.MAX_WHOISALIVE_MANAGER_COUNT, ManagerTestHelper.MAX_WHOISALIVE_MANAGER_COUNT); diff --git a/src/test/java/org/fogbowcloud/manager/xmpp/TestRequestRemoteInstance.java b/src/test/java/org/fogbowcloud/manager/xmpp/TestRequestRemoteInstance.java index a72be21c..9c6ddfd8 100644 --- a/src/test/java/org/fogbowcloud/manager/xmpp/TestRequestRemoteInstance.java +++ b/src/test/java/org/fogbowcloud/manager/xmpp/TestRequestRemoteInstance.java @@ -57,9 +57,11 @@ public void testRequestRemoteInstanceAsynchronously() throws Exception { INSTANCE_DEFAULT); final BlockingQueue bq = new LinkedBlockingQueue(); - ManagerPacketHelper.asynchronousRemoteRequest(request, - DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, request.getFederationToken(), - managerTestHelper.createPacketSender(), new AsynchronousRequestCallback() { + + ManagerPacketHelper.asynchronousRemoteRequest(request.getId(), request.getCategories(), + request.getxOCCIAtt(), DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, + request.getFederationToken(), managerTestHelper.createPacketSender(), + new AsynchronousRequestCallback() { @Override public void success(String instanceId) { diff --git a/src/test/java/org/fogbowcloud/manager/xmpp/TestWhoIsAlive.java b/src/test/java/org/fogbowcloud/manager/xmpp/TestWhoIsAlive.java index 47fc84a6..4227bdef 100644 --- a/src/test/java/org/fogbowcloud/manager/xmpp/TestWhoIsAlive.java +++ b/src/test/java/org/fogbowcloud/manager/xmpp/TestWhoIsAlive.java @@ -93,11 +93,6 @@ public boolean accept(Packet packet) { // The other member and the manager itself Assert.assertEquals(2, managerXmppComponent.getManagerFacade() .getMembers().size()); - Assert.assertEquals(2, managerXmppComponent.getManagerFacade() - .getMembers().get(0).getResourcesInfo().getFlavors().size()); - Assert.assertEquals("small", managerXmppComponent.getManagerFacade() - .getMembers().get(0).getResourcesInfo().getFlavors().get(0) - .getName()); xmppClient.disconnect(); } @@ -152,9 +147,6 @@ public boolean accept(Packet packet) { // The other member and the manager itself Assert.assertEquals(2, managerXmppComponent.getManagerFacade() .getMembers().size()); - Assert.assertEquals("small", managerXmppComponent.getManagerFacade() - .getMembers().get(0).getResourcesInfo().getFlavors().get(0) - .getName()); xmppClient.disconnect(); } diff --git a/src/test/resources/imagestorage/vmcatcher/image.list b/src/test/resources/imagestorage/vmcatcher/image.list new file mode 100644 index 00000000..54f0a60d --- /dev/null +++ b/src/test/resources/imagestorage/vmcatcher/image.list @@ -0,0 +1,105 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="----30588B98B0E38B9A91CE05FB2BFC72DB" + +This is an S/MIME signed message + +------30588B98B0E38B9A91CE05FB2BFC72DB +{ + "hv:imagelist": { + "dc:date:created": "2014-10-29T16:53:55Z", + "dc:date:expires": "2499-12-31T22:00:00Z", + "dc:description": "Scientific Linux 6.5 Minimal OS", + "dc:identifier": "776690f9-d023-44c6-9923-b66ed853d77b", + "dc:source": "https://appdb.egi.eu/", + "dc:title": "Scientific Linux 6.5 Minimal", + "ad:swid": "799", + "hv:endorser": { + "hv:x509": { + "dc:creator": "EGI Applications Database", + "hv:ca": "/DC=ORG/DC=SEE-GRID/CN=SEE-GRID CA 2013", + "hv:dn": "/DC=EU/DC=EGI/C=NL/O=Hosts/O=EGI.eu/CN=appdb.egi.eu", + "hv:email": "appdb-support@iasa.gr" + } + }, + "hv:images": [ + { + "hv:image": { + "dc:description": "", + "dc:identifier": "2c24de6c-e385-49f1-b64f-f9ff35e70f43", + "ad:mpuri": "https://appdb.egi.eu/store/vm/image/2c24de6c-e385-49f1-b64f-f9ff35e70f43:3639/", + "dc:title": "OS Disk Image", + "ad:group": "Scientific Linux 6.5 Minimal OS", + "hv:hypervisor": "QEMU-KVM", + "hv:format": "OVA", + "hv:ram_minimum": "512", + "ad:ram_recommended": "1024", + "hv:core_minimum": "1", + "ad:core_recommended": "2", + "hv:size": "431902720", + "hv:uri": "http://appliance-repo.egi.eu/images/base/SL-6.5-x86_64-minimal/20141029/SL6.5-20141029.ova", + "hv:version": "20141029", + "sl:arch": "x86_64", + "sl:checksum:sha512": "a9690261dca2402ff9e42fff3031c0fe51992f3bac8e3791c09e9eb8edb7458578d8ca32559047f563d2e1e8ce42fcd867dd83d468abb3cd58e33eb4b18edad4", + "sl:comments": "", + "sl:os": "Linux", + "sl:osname": "Scientific Linux", + "sl:osversion": "Scientific Linux 6.5", + "ad:user:fullname": "Fernandez Enol", + "ad:user:guid": "e85470d8-2af9-11e0-8c26-0014c23dfd8c", + "ad:user:uri": "https://appdb.egi.eu/store/person/enol.fernandez" + } + } + ], + "hv:uri": "https://vmcaster.appdb.egi.eu/store/vappliance/scientific.linux.6.4.minimal/image.list", + "hv:version": "20141029" + } +} + +------30588B98B0E38B9A91CE05FB2BFC72DB +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHbQYJKoZIhvcNAQcCoIIHXjCCB1oCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3 +DQEHAaCCBOQwggTgMIIDyKADAgECAgEjMA0GCSqGSIb3DQEBCwUAMEoxEzARBgoJ +kiaJk/IsZAEZFgNPUkcxGDAWBgoJkiaJk/IsZAEZFghTRUUtR1JJRDEZMBcGA1UE +AxMQU0VFLUdSSUQgQ0EgMjAxMzAeFw0xNDA3MTEwNzQ3MDFaFw0xNTA3MTEwNzQ3 +MDFaMG4xEjAQBgoJkiaJk/IsZAEZFgJFVTETMBEGCgmSJomT8ixkARkWA0VHSTEL +MAkGA1UEBhMCTkwxDjAMBgNVBAoTBUhvc3RzMQ8wDQYDVQQKEwZFR0kuZXUxFTAT +BgNVBAMTDGFwcGRiLmVnaS5ldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN7WawAUAFAPO+lhysWzI+vmnqDxk7O3dXzppl9L+IN1nfPmbNcBSw4AbR2q +VhENBDWn92skVduUiE1Do8d8ZJtGrrzeeloC5lHn4vkxScy5HSbrPec+aNECPTzi +b8PTlP3hAxAVBwkTboPYJyc5ow7AXM+SZACQzaeM4UuFa/w0Sp52ojv87hUDDVd3 +YMCd9AtfsZi+PVzEZFl3pbJyQ3bdaCOYhC6zbgfVfUH4em0xOnVVgUfCLVn20k4W +SHcvWTqOrL/lSU4jir6ex5j3zMmIYtzlFx9LaNBmBtIdMbZ+WFWP2vQMxjiCOfOM +FPIM6cVUw7ub0zZYL8IYUhAawNcCAwEAAaOCAaswggGnMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgSwMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcDAgYI +KwYBBQUHAwQwHQYDVR0OBBYEFO1BKNJtjUY5+HfkNsNEvUNdaVfyMHIGA1UdIwRr +MGmAFLTbgExuumOjXH7fknD2mC0aHHCAoU6kTDBKMRMwEQYKCZImiZPyLGQBGRYD +T1JHMRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklE +IENBIDIwMTOCAQAwFwYDVR0RBBAwDoIMYXBwZGIuZWdpLmV1MEQGA1UdHwQ9MDsw +OaA3oDWGM2h0dHA6Ly9jcmwuaGVsbGFzZ3JpZC5nci9zZWVncmlkLWNhLTIwMTMv +Y3JsLXYyLnBlbTBsBgNVHSAEZTBjMGEGDSsGAQQBgYEDFAIBAgQwUDBOBggrBgEF +BQcCARZCaHR0cDovL3NlZS1ncmlkLWNhLmhlbGxhc2dyaWQuZ3IvYXNzZXRzL1NF +RS1HUklELUNBLUNQLUNQUy0yLjQucGRmMA0GCSqGSIb3DQEBCwUAA4IBAQDhrV+D +3mOtbTziSUQ8Doz3WnN7YggQxU9Wq6DP54hWEDVzSLRX5EGwcAmj0G2Bhigj2F/N +ta70tz4TsrWjMeQGrV01TuPkR3sj3JOZJmHK4k/y1eNCEhEEAhH4e4F3oBzwgNIb +J+1n1nq6bilplmz5Ktn46yVwfm51qXX592yP/wYoDeSm7XeHQa8yVZbsmXAiZxIM +VJqmSp/OAAtIixcUNK2C3+xmWEaObCrheT3pkIix91mNJQtSfpi/VXz91Qr+9Fa6 +DG5K7sEj+21CcaMk4p2aR5ntGRSN0WdqhpTpZBvsmHvjd+23RRDztWdi9McttOwc +DlWylveScIkIbfQwMYICUTCCAk0CAQEwTzBKMRMwEQYKCZImiZPyLGQBGRYDT1JH +MRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklEIENB +IDIwMTMCASMwCQYFKw4DAhoFAKCB2DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB +MBwGCSqGSIb3DQEJBTEPFw0xNDEwMjkxNjUzNTdaMCMGCSqGSIb3DQEJBDEWBBSj +oWE1pqpxTE3KQXPOSYDQaDX+wDB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQB +KjALBglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3 +DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDAN +BgkqhkiG9w0BAQEFAASCAQCB7fSVOzcnV29eungoUhMGYWf3uiE9yjRFQTqV3Dfb +KRQmyxHUuaAM6Tsxz3BV0MRudcqdxIS23J77jzG2XPt9UmEceFykdvHh3yki0aYV +0I1ZmIhy/r/2WfUcNC05wPr3Z/ZTPjIdM8qhxJfmv30K3BV4hzTb4p+uUiM8Fg2r +07Qbfw6b0WBvG7aam/JA2nO7FGxNhaduI8mmEHhlMc8YQBoLqRFEqKe2wB9J2rZf +1dXdkhfBmlsbBeuMkFl6pXww7QW3GMOG3V32ML0C2iLCtvzbNs2pB7NZ5vFduQdh +7OQ+yXJb+hQCanMzg4/aAUwESF5EcqUuxWY9Sb+svpts + +------30588B98B0E38B9A91CE05FB2BFC72DB-- + diff --git a/src/test/resources/imagestorage/vmcatcher/image.list.noidentifier b/src/test/resources/imagestorage/vmcatcher/image.list.noidentifier new file mode 100644 index 00000000..e4c26196 --- /dev/null +++ b/src/test/resources/imagestorage/vmcatcher/image.list.noidentifier @@ -0,0 +1,104 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="----30588B98B0E38B9A91CE05FB2BFC72DB" + +This is an S/MIME signed message + +------30588B98B0E38B9A91CE05FB2BFC72DB +{ + "hv:imagelist": { + "dc:date:created": "2014-10-29T16:53:55Z", + "dc:date:expires": "2499-12-31T22:00:00Z", + "dc:description": "Scientific Linux 6.5 Minimal OS", + "dc:source": "https://appdb.egi.eu/", + "dc:title": "Scientific Linux 6.5 Minimal", + "ad:swid": "799", + "hv:endorser": { + "hv:x509": { + "dc:creator": "EGI Applications Database", + "hv:ca": "/DC=ORG/DC=SEE-GRID/CN=SEE-GRID CA 2013", + "hv:dn": "/DC=EU/DC=EGI/C=NL/O=Hosts/O=EGI.eu/CN=appdb.egi.eu", + "hv:email": "appdb-support@iasa.gr" + } + }, + "hv:images": [ + { + "hv:image": { + "dc:description": "", + "dc:identifier": "2c24de6c-e385-49f1-b64f-f9ff35e70f43", + "ad:mpuri": "https://appdb.egi.eu/store/vm/image/2c24de6c-e385-49f1-b64f-f9ff35e70f43:3639/", + "dc:title": "OS Disk Image", + "ad:group": "Scientific Linux 6.5 Minimal OS", + "hv:hypervisor": "QEMU-KVM", + "hv:format": "OVA", + "hv:ram_minimum": "512", + "ad:ram_recommended": "1024", + "hv:core_minimum": "1", + "ad:core_recommended": "2", + "hv:size": "431902720", + "hv:uri": "http://appliance-repo.egi.eu/images/base/SL-6.5-x86_64-minimal/20141029/SL6.5-20141029.ova", + "hv:version": "20141029", + "sl:arch": "x86_64", + "sl:checksum:sha512": "a9690261dca2402ff9e42fff3031c0fe51992f3bac8e3791c09e9eb8edb7458578d8ca32559047f563d2e1e8ce42fcd867dd83d468abb3cd58e33eb4b18edad4", + "sl:comments": "", + "sl:os": "Linux", + "sl:osname": "Scientific Linux", + "sl:osversion": "Scientific Linux 6.5", + "ad:user:fullname": "Fernandez Enol", + "ad:user:guid": "e85470d8-2af9-11e0-8c26-0014c23dfd8c", + "ad:user:uri": "https://appdb.egi.eu/store/person/enol.fernandez" + } + } + ], + "hv:uri": "https://vmcaster.appdb.egi.eu/store/vappliance/scientific.linux.6.4.minimal/image.list", + "hv:version": "20141029" + } +} + +------30588B98B0E38B9A91CE05FB2BFC72DB +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHbQYJKoZIhvcNAQcCoIIHXjCCB1oCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3 +DQEHAaCCBOQwggTgMIIDyKADAgECAgEjMA0GCSqGSIb3DQEBCwUAMEoxEzARBgoJ +kiaJk/IsZAEZFgNPUkcxGDAWBgoJkiaJk/IsZAEZFghTRUUtR1JJRDEZMBcGA1UE +AxMQU0VFLUdSSUQgQ0EgMjAxMzAeFw0xNDA3MTEwNzQ3MDFaFw0xNTA3MTEwNzQ3 +MDFaMG4xEjAQBgoJkiaJk/IsZAEZFgJFVTETMBEGCgmSJomT8ixkARkWA0VHSTEL +MAkGA1UEBhMCTkwxDjAMBgNVBAoTBUhvc3RzMQ8wDQYDVQQKEwZFR0kuZXUxFTAT +BgNVBAMTDGFwcGRiLmVnaS5ldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN7WawAUAFAPO+lhysWzI+vmnqDxk7O3dXzppl9L+IN1nfPmbNcBSw4AbR2q +VhENBDWn92skVduUiE1Do8d8ZJtGrrzeeloC5lHn4vkxScy5HSbrPec+aNECPTzi +b8PTlP3hAxAVBwkTboPYJyc5ow7AXM+SZACQzaeM4UuFa/w0Sp52ojv87hUDDVd3 +YMCd9AtfsZi+PVzEZFl3pbJyQ3bdaCOYhC6zbgfVfUH4em0xOnVVgUfCLVn20k4W +SHcvWTqOrL/lSU4jir6ex5j3zMmIYtzlFx9LaNBmBtIdMbZ+WFWP2vQMxjiCOfOM +FPIM6cVUw7ub0zZYL8IYUhAawNcCAwEAAaOCAaswggGnMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgSwMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcDAgYI +KwYBBQUHAwQwHQYDVR0OBBYEFO1BKNJtjUY5+HfkNsNEvUNdaVfyMHIGA1UdIwRr +MGmAFLTbgExuumOjXH7fknD2mC0aHHCAoU6kTDBKMRMwEQYKCZImiZPyLGQBGRYD +T1JHMRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklE +IENBIDIwMTOCAQAwFwYDVR0RBBAwDoIMYXBwZGIuZWdpLmV1MEQGA1UdHwQ9MDsw +OaA3oDWGM2h0dHA6Ly9jcmwuaGVsbGFzZ3JpZC5nci9zZWVncmlkLWNhLTIwMTMv +Y3JsLXYyLnBlbTBsBgNVHSAEZTBjMGEGDSsGAQQBgYEDFAIBAgQwUDBOBggrBgEF +BQcCARZCaHR0cDovL3NlZS1ncmlkLWNhLmhlbGxhc2dyaWQuZ3IvYXNzZXRzL1NF +RS1HUklELUNBLUNQLUNQUy0yLjQucGRmMA0GCSqGSIb3DQEBCwUAA4IBAQDhrV+D +3mOtbTziSUQ8Doz3WnN7YggQxU9Wq6DP54hWEDVzSLRX5EGwcAmj0G2Bhigj2F/N +ta70tz4TsrWjMeQGrV01TuPkR3sj3JOZJmHK4k/y1eNCEhEEAhH4e4F3oBzwgNIb +J+1n1nq6bilplmz5Ktn46yVwfm51qXX592yP/wYoDeSm7XeHQa8yVZbsmXAiZxIM +VJqmSp/OAAtIixcUNK2C3+xmWEaObCrheT3pkIix91mNJQtSfpi/VXz91Qr+9Fa6 +DG5K7sEj+21CcaMk4p2aR5ntGRSN0WdqhpTpZBvsmHvjd+23RRDztWdi9McttOwc +DlWylveScIkIbfQwMYICUTCCAk0CAQEwTzBKMRMwEQYKCZImiZPyLGQBGRYDT1JH +MRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklEIENB +IDIwMTMCASMwCQYFKw4DAhoFAKCB2DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB +MBwGCSqGSIb3DQEJBTEPFw0xNDEwMjkxNjUzNTdaMCMGCSqGSIb3DQEJBDEWBBSj +oWE1pqpxTE3KQXPOSYDQaDX+wDB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQB +KjALBglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3 +DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDAN +BgkqhkiG9w0BAQEFAASCAQCB7fSVOzcnV29eungoUhMGYWf3uiE9yjRFQTqV3Dfb +KRQmyxHUuaAM6Tsxz3BV0MRudcqdxIS23J77jzG2XPt9UmEceFykdvHh3yki0aYV +0I1ZmIhy/r/2WfUcNC05wPr3Z/ZTPjIdM8qhxJfmv30K3BV4hzTb4p+uUiM8Fg2r +07Qbfw6b0WBvG7aam/JA2nO7FGxNhaduI8mmEHhlMc8YQBoLqRFEqKe2wB9J2rZf +1dXdkhfBmlsbBeuMkFl6pXww7QW3GMOG3V32ML0C2iLCtvzbNs2pB7NZ5vFduQdh +7OQ+yXJb+hQCanMzg4/aAUwESF5EcqUuxWY9Sb+svpts + +------30588B98B0E38B9A91CE05FB2BFC72DB-- + diff --git a/src/test/resources/imagestorage/vmcatcher/image.list.noname b/src/test/resources/imagestorage/vmcatcher/image.list.noname new file mode 100644 index 00000000..54f0a60d --- /dev/null +++ b/src/test/resources/imagestorage/vmcatcher/image.list.noname @@ -0,0 +1,105 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha1"; boundary="----30588B98B0E38B9A91CE05FB2BFC72DB" + +This is an S/MIME signed message + +------30588B98B0E38B9A91CE05FB2BFC72DB +{ + "hv:imagelist": { + "dc:date:created": "2014-10-29T16:53:55Z", + "dc:date:expires": "2499-12-31T22:00:00Z", + "dc:description": "Scientific Linux 6.5 Minimal OS", + "dc:identifier": "776690f9-d023-44c6-9923-b66ed853d77b", + "dc:source": "https://appdb.egi.eu/", + "dc:title": "Scientific Linux 6.5 Minimal", + "ad:swid": "799", + "hv:endorser": { + "hv:x509": { + "dc:creator": "EGI Applications Database", + "hv:ca": "/DC=ORG/DC=SEE-GRID/CN=SEE-GRID CA 2013", + "hv:dn": "/DC=EU/DC=EGI/C=NL/O=Hosts/O=EGI.eu/CN=appdb.egi.eu", + "hv:email": "appdb-support@iasa.gr" + } + }, + "hv:images": [ + { + "hv:image": { + "dc:description": "", + "dc:identifier": "2c24de6c-e385-49f1-b64f-f9ff35e70f43", + "ad:mpuri": "https://appdb.egi.eu/store/vm/image/2c24de6c-e385-49f1-b64f-f9ff35e70f43:3639/", + "dc:title": "OS Disk Image", + "ad:group": "Scientific Linux 6.5 Minimal OS", + "hv:hypervisor": "QEMU-KVM", + "hv:format": "OVA", + "hv:ram_minimum": "512", + "ad:ram_recommended": "1024", + "hv:core_minimum": "1", + "ad:core_recommended": "2", + "hv:size": "431902720", + "hv:uri": "http://appliance-repo.egi.eu/images/base/SL-6.5-x86_64-minimal/20141029/SL6.5-20141029.ova", + "hv:version": "20141029", + "sl:arch": "x86_64", + "sl:checksum:sha512": "a9690261dca2402ff9e42fff3031c0fe51992f3bac8e3791c09e9eb8edb7458578d8ca32559047f563d2e1e8ce42fcd867dd83d468abb3cd58e33eb4b18edad4", + "sl:comments": "", + "sl:os": "Linux", + "sl:osname": "Scientific Linux", + "sl:osversion": "Scientific Linux 6.5", + "ad:user:fullname": "Fernandez Enol", + "ad:user:guid": "e85470d8-2af9-11e0-8c26-0014c23dfd8c", + "ad:user:uri": "https://appdb.egi.eu/store/person/enol.fernandez" + } + } + ], + "hv:uri": "https://vmcaster.appdb.egi.eu/store/vappliance/scientific.linux.6.4.minimal/image.list", + "hv:version": "20141029" + } +} + +------30588B98B0E38B9A91CE05FB2BFC72DB +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIHbQYJKoZIhvcNAQcCoIIHXjCCB1oCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3 +DQEHAaCCBOQwggTgMIIDyKADAgECAgEjMA0GCSqGSIb3DQEBCwUAMEoxEzARBgoJ +kiaJk/IsZAEZFgNPUkcxGDAWBgoJkiaJk/IsZAEZFghTRUUtR1JJRDEZMBcGA1UE +AxMQU0VFLUdSSUQgQ0EgMjAxMzAeFw0xNDA3MTEwNzQ3MDFaFw0xNTA3MTEwNzQ3 +MDFaMG4xEjAQBgoJkiaJk/IsZAEZFgJFVTETMBEGCgmSJomT8ixkARkWA0VHSTEL +MAkGA1UEBhMCTkwxDjAMBgNVBAoTBUhvc3RzMQ8wDQYDVQQKEwZFR0kuZXUxFTAT +BgNVBAMTDGFwcGRiLmVnaS5ldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN7WawAUAFAPO+lhysWzI+vmnqDxk7O3dXzppl9L+IN1nfPmbNcBSw4AbR2q +VhENBDWn92skVduUiE1Do8d8ZJtGrrzeeloC5lHn4vkxScy5HSbrPec+aNECPTzi +b8PTlP3hAxAVBwkTboPYJyc5ow7AXM+SZACQzaeM4UuFa/w0Sp52ojv87hUDDVd3 +YMCd9AtfsZi+PVzEZFl3pbJyQ3bdaCOYhC6zbgfVfUH4em0xOnVVgUfCLVn20k4W +SHcvWTqOrL/lSU4jir6ex5j3zMmIYtzlFx9LaNBmBtIdMbZ+WFWP2vQMxjiCOfOM +FPIM6cVUw7ub0zZYL8IYUhAawNcCAwEAAaOCAaswggGnMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgSwMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcDAgYI +KwYBBQUHAwQwHQYDVR0OBBYEFO1BKNJtjUY5+HfkNsNEvUNdaVfyMHIGA1UdIwRr +MGmAFLTbgExuumOjXH7fknD2mC0aHHCAoU6kTDBKMRMwEQYKCZImiZPyLGQBGRYD +T1JHMRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklE +IENBIDIwMTOCAQAwFwYDVR0RBBAwDoIMYXBwZGIuZWdpLmV1MEQGA1UdHwQ9MDsw +OaA3oDWGM2h0dHA6Ly9jcmwuaGVsbGFzZ3JpZC5nci9zZWVncmlkLWNhLTIwMTMv +Y3JsLXYyLnBlbTBsBgNVHSAEZTBjMGEGDSsGAQQBgYEDFAIBAgQwUDBOBggrBgEF +BQcCARZCaHR0cDovL3NlZS1ncmlkLWNhLmhlbGxhc2dyaWQuZ3IvYXNzZXRzL1NF +RS1HUklELUNBLUNQLUNQUy0yLjQucGRmMA0GCSqGSIb3DQEBCwUAA4IBAQDhrV+D +3mOtbTziSUQ8Doz3WnN7YggQxU9Wq6DP54hWEDVzSLRX5EGwcAmj0G2Bhigj2F/N +ta70tz4TsrWjMeQGrV01TuPkR3sj3JOZJmHK4k/y1eNCEhEEAhH4e4F3oBzwgNIb +J+1n1nq6bilplmz5Ktn46yVwfm51qXX592yP/wYoDeSm7XeHQa8yVZbsmXAiZxIM +VJqmSp/OAAtIixcUNK2C3+xmWEaObCrheT3pkIix91mNJQtSfpi/VXz91Qr+9Fa6 +DG5K7sEj+21CcaMk4p2aR5ntGRSN0WdqhpTpZBvsmHvjd+23RRDztWdi9McttOwc +DlWylveScIkIbfQwMYICUTCCAk0CAQEwTzBKMRMwEQYKCZImiZPyLGQBGRYDT1JH +MRgwFgYKCZImiZPyLGQBGRYIU0VFLUdSSUQxGTAXBgNVBAMTEFNFRS1HUklEIENB +IDIwMTMCASMwCQYFKw4DAhoFAKCB2DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB +MBwGCSqGSIb3DQEJBTEPFw0xNDEwMjkxNjUzNTdaMCMGCSqGSIb3DQEJBDEWBBSj +oWE1pqpxTE3KQXPOSYDQaDX+wDB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQB +KjALBglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3 +DQMCAgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDAN +BgkqhkiG9w0BAQEFAASCAQCB7fSVOzcnV29eungoUhMGYWf3uiE9yjRFQTqV3Dfb +KRQmyxHUuaAM6Tsxz3BV0MRudcqdxIS23J77jzG2XPt9UmEceFykdvHh3yki0aYV +0I1ZmIhy/r/2WfUcNC05wPr3Z/ZTPjIdM8qhxJfmv30K3BV4hzTb4p+uUiM8Fg2r +07Qbfw6b0WBvG7aam/JA2nO7FGxNhaduI8mmEHhlMc8YQBoLqRFEqKe2wB9J2rZf +1dXdkhfBmlsbBeuMkFl6pXww7QW3GMOG3V32ML0C2iLCtvzbNs2pB7NZ5vFduQdh +7OQ+yXJb+hQCanMzg4/aAUwESF5EcqUuxWY9Sb+svpts + +------30588B98B0E38B9A91CE05FB2BFC72DB-- + diff --git a/src/test/resources/server.id_rsa.pub b/src/test/resources/server.id_rsa.pub new file mode 100644 index 00000000..ff8fb727 --- /dev/null +++ b/src/test/resources/server.id_rsa.pub @@ -0,0 +1 @@ +server-public-key \ No newline at end of file