/******************************************************************************* * Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved * * 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. *******************************************************************************/ package org.cloudifysource.rest.controllers.helpers; import java.util.HashMap; import java.util.Map; import net.jini.core.lease.Lease; import org.apache.commons.lang.StringUtils; import org.cloudifysource.dsl.internal.CloudifyMessageKeys; import org.cloudifysource.dsl.utils.ServiceUtils; import org.cloudifysource.rest.controllers.RestErrorException; import org.cloudifysource.rest.exceptions.ResourceNotFoundException; import org.cloudifysource.utilitydomain.kvstorage.spaceentries.AbstractCloudifyAttribute; import org.cloudifysource.utilitydomain.kvstorage.spaceentries.ApplicationCloudifyAttribute; import org.cloudifysource.utilitydomain.kvstorage.spaceentries.GlobalCloudifyAttribute; import org.cloudifysource.utilitydomain.kvstorage.spaceentries.InstanceCloudifyAttribute; import org.cloudifysource.utilitydomain.kvstorage.spaceentries.ServiceCloudifyAttribute; import org.openspaces.admin.Admin; import org.openspaces.admin.application.Application; import org.openspaces.admin.pu.ProcessingUnit; import org.openspaces.admin.pu.ProcessingUnitInstance; import org.openspaces.core.GigaSpace; import com.gigaspaces.client.WriteModifiers; /** * Created with IntelliJ IDEA. * User: elip * Date: 5/22/13 * Time: 1:11 PM */ public class ControllerHelper { private GigaSpace gigaSpace; private Admin admin; public ControllerHelper(final GigaSpace gigaSpace, final Admin admin) { this.gigaSpace = gigaSpace; this.admin = admin; } /** * Retrieves an application by name. * @param appName The application name. * @return {@link org.openspaces.admin.application.Application} - The application. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the application is not found. */ public Application getApplication(final String appName) throws ResourceNotFoundException { Application application = admin.getApplications().getApplication(appName); if (application == null) { throw new ResourceNotFoundException(appName); } return application; } /** * Retrieves a service instance from a processing unit by instance id. * @param processingUnit The processing unit. * @param instanceId The instance id. * @return {@link org.openspaces.admin.pu.ProcessingUnitInstance} - The processing unit instance. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the instance does not exist. */ public ProcessingUnitInstance getServiceInstance(final ProcessingUnit processingUnit, final int instanceId) throws ResourceNotFoundException { ProcessingUnitInstance pui = null; for (ProcessingUnitInstance processingUnitInstance : processingUnit.getInstances()) { if (processingUnitInstance.getInstanceId() == instanceId) { pui = processingUnitInstance; break; } } if (pui == null) { throw new ResourceNotFoundException(processingUnit.getName() + "[" + instanceId + "]"); } return pui; } /** * Retrieves a service by application name and service name. * @param appName The application name. * @param serviceName The service name. * @return {@link org.openspaces.admin.pu.ProcessingUnit} - The service. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the service is not found. */ public ProcessingUnit getService(final String appName, final String serviceName) throws ResourceNotFoundException { String absolutePUName = ServiceUtils.getAbsolutePUName(appName, serviceName); ProcessingUnit processingUnit = admin.getProcessingUnits().getProcessingUnit(absolutePUName); if (processingUnit == null) { throw new ResourceNotFoundException(ServiceUtils.getAbsolutePUName(appName, serviceName)); } return processingUnit; } /** * Retrieves a service instance environment variable from the JVM's environment. * @param serviceInstance The service instance. * @param variable The name of the variable. * @return the value of the variable. */ public String getServiceInstanceEnvVariable(final ProcessingUnitInstance serviceInstance, final String variable) { if (StringUtils.isNotBlank(variable)) { return serviceInstance.getVirtualMachine().getDetails().getEnvironmentVariables().get(variable); } return null; } /** * Retrieves a service instance by application name, service name, and instance id. * @param appName The application name. * @param serviceName The service name. * @param instanceId The instance id. * @return {@link org.openspaces.admin.pu.ProcessingUnitInstance} - The processing unit instance. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the instance does not exist. */ public ProcessingUnitInstance getServiceInstance(final String appName, final String serviceName, final int instanceId) throws ResourceNotFoundException { ProcessingUnit processingUnit = getService(appName, serviceName); return getServiceInstance(processingUnit, instanceId); } /** * Retrieves service instance level attributes. * @param appName The application name. * @param serviceName The service name. * @param instanceId The instance id. * @return An instance of {@link org.cloudifysource.dsl.rest.response.GetServiceInstanceAttributesResponse} * containing all the service instance attributes names and values. */ public Map<String, Object> getAttributes(final String appName, final String serviceName, final Integer instanceId) { final AbstractCloudifyAttribute templateAttribute = createCloudifyAttribute(appName, serviceName, instanceId, null, null); // read the matching multiple attributes from the space final AbstractCloudifyAttribute[] currAttributes = gigaSpace.readMultiple(templateAttribute); // create new map for response Map<String, Object> attributes = new HashMap<String, Object>(); // current attribute for application is null if (currAttributes == null) { // return empty attributes return attributes; } // update attribute object with current attributes for (AbstractCloudifyAttribute applicationCloudifyAttribute : currAttributes) { if (applicationCloudifyAttribute.getValue() != null) { attributes.put(applicationCloudifyAttribute.getKey(), applicationCloudifyAttribute.getValue().toString()); } } // return attributes return attributes; } /** * Creates a cloudify attribute. * @param applicationName The application name. * @param serviceName The service name. * @param instanceId The instance id. * @param name The attribute name. * @param value The attribute value. * @return the attribute. */ public AbstractCloudifyAttribute createCloudifyAttribute(final String applicationName, final String serviceName, final Integer instanceId, final String name, final Object value) { // global if (applicationName == null) { return new GlobalCloudifyAttribute(name, value); } // application if (serviceName == null) { return new ApplicationCloudifyAttribute(applicationName, name, value); } // service if (instanceId == null) { return new ServiceCloudifyAttribute(applicationName, serviceName, name, value); } // instance return new InstanceCloudifyAttribute(applicationName, serviceName, instanceId, name, value); } /** * Delete an instance level attribute. * @param appName The application name. * @param serviceName The service name. * @param instanceId The instance id. * @param attributeName The attribute name. * @return The previous value for this attribute in the response. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the requested service or service instance does not exist. * @throws org.cloudifysource.rest.controllers.RestErrorException Thrown in case the requested attribute name is empty. */ public Object deleteAttribute(final String appName, final String serviceName, final Integer instanceId, final String attributeName) throws ResourceNotFoundException, RestErrorException { // attribute name is null if (StringUtils.isBlank(attributeName)) { throw new RestErrorException(CloudifyMessageKeys.EMPTY_ATTRIBUTE_NAME.getName()); } // get attribute template final AbstractCloudifyAttribute attributeTemplate = createCloudifyAttribute(appName, serviceName, instanceId, attributeName, null); // delete value final AbstractCloudifyAttribute previousValue = gigaSpace.take(attributeTemplate); // not exist attribute name if (previousValue == null) { throw new ResourceNotFoundException(attributeName); } // return previous value for attribute that already deleted return previousValue.getValue(); } /** * Sets service instance level attributes for the given application. * @param appName The application name. * @param serviceName The service name. * @param instanceId The instance id. * @param attributesMap specifying the attributes names and values. * @throws org.cloudifysource.rest.controllers.RestErrorException Thrown in case the request body is empty. * @throws org.cloudifysource.rest.exceptions.ResourceNotFoundException Thrown in case the service instance does not exist. */ public void setAttributes(final String appName, final String serviceName, final Integer instanceId, final Map<String, Object> attributesMap) throws RestErrorException { // validate attributes map if (attributesMap == null) { throw new RestErrorException(CloudifyMessageKeys.EMPTY_REQUEST_BODY_ERROR.getName()); } // create templates attributes to write final AbstractCloudifyAttribute[] attributesToWrite = new AbstractCloudifyAttribute[attributesMap.size()]; int i = 0; for (final Map.Entry<String, Object> attrEntry : attributesMap.entrySet()) { final AbstractCloudifyAttribute newAttr = createCloudifyAttribute(appName, serviceName, instanceId, attrEntry.getKey(), null); gigaSpace.take(newAttr); newAttr.setValue(attrEntry.getValue()); attributesToWrite[i++] = newAttr; } // write attributes gigaSpace.writeMultiple(attributesToWrite, Lease.FOREVER, WriteModifiers.UPDATE_OR_WRITE); } }