/*******************************************************************************
* Copyright (c) 2012 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;
import static org.cloudifysource.rest.ResponseConstants.HTTP_OK;
import static org.cloudifysource.rest.util.RestUtils.successStatus;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.jini.core.lease.Lease;
import org.cloudifysource.dsl.utils.ServiceUtils;
import org.cloudifysource.restDoclet.annotations.JsonRequestExample;
import org.cloudifysource.restDoclet.annotations.JsonResponseExample;
import org.cloudifysource.restDoclet.annotations.PossibleResponseStatus;
import org.cloudifysource.restDoclet.annotations.PossibleResponseStatuses;
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.codehaus.jackson.map.ObjectMapper;
import org.openspaces.core.GigaSpace;
import org.openspaces.core.context.GigaSpaceContext;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.gigaspaces.client.WriteModifiers;
/**
* @author noak
* @since 2.2.0
*/
@Controller
@RequestMapping("/attributes")
public class AttributesController {
@GigaSpaceContext(name = "gigaSpace")
private GigaSpace gigaSpace;
private static final Logger logger = Logger.getLogger(AttributesController.class.getName());
/**
* Exception handler for all of known internal server exceptions.
*
* @param response
* The response object to edit, if not committed yet.
* @param e
* The exception that occurred, from which data is read for logging and for the response error message.
* @throws IOException
* Reporting failure to edit the response object
*/
@ExceptionHandler(RestErrorException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public void handleServerErrors(final HttpServletResponse response,
final RestErrorException e) throws IOException {
if (response.isCommitted()) {
logger.log(
Level.WARNING,
"Caught exception, but response already commited. Not sending error message based on exception",
e);
} else {
final Map<String, Object> errorDescriptionMap = e
.getErrorDescription();
final String errorMap = new ObjectMapper()
.writeValueAsString(errorDescriptionMap);
logger.log(Level.INFO, "caught exception. Sending response message "
+ errorDescriptionMap.get("error"), e);
final byte[] messageBytes = errorMap.getBytes();
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(messageBytes);
}
}
/**
* Gets an attribute value, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @param attributeName
* The name (key) of the attribute to get.
* @return The attribute's value.
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}/{attributeName}",
method = RequestMethod.GET)
@ResponseBody
public Object getInstanceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final int instanceId,
@PathVariable final String attributeName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get attribute " + attributeName + " of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName) + " instance number " + instanceId
+ " of application " + applicationName);
}
final InstanceCloudifyAttribute templateAttribute =
new InstanceCloudifyAttribute(applicationName, serviceName, instanceId, attributeName, null);
// read the matching attribute from the space
final InstanceCloudifyAttribute valueEntry = gigaSpace.read(templateAttribute);
final Object value = valueEntry != null ? valueEntry.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Gets multiple attributes' values, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @return a Map containing the attributes' names (keys) and values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}",
method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getInstanceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName,
@PathVariable final int instanceId) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get all attributes of instance number " + instanceId + " of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName) + " of application "
+ applicationName);
}
final InstanceCloudifyAttribute templateAttribute = new InstanceCloudifyAttribute(applicationName,
serviceName, instanceId, null, null);
// read the matching multiple attributes from the space
final InstanceCloudifyAttribute[] attributes = gigaSpace.readMultiple(templateAttribute);
final Map<String, Object> attributesMap = new HashMap<String, Object>();
for (final InstanceCloudifyAttribute attribute : attributes) {
attributesMap.put(attribute.getKey(), attribute.getValue());
}
return attributesMap;
}
/**
* Gets multiple attributes' values, from all instances, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @return a Map containing the attributes' names (keys) and values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"instanceId:attribute1Name\":\"attribute1Value\","
+ "\"instanceId:attribute2Name\":\"attribute2Value\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}",
method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getAllInstanceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get all instance attributes of service "
+ serviceName + " of application "
+ applicationName);
}
final InstanceCloudifyAttribute templateAttribute = new InstanceCloudifyAttribute(applicationName,
serviceName, null, null, null);
// read the matching multiple attributes from the space
final InstanceCloudifyAttribute[] attributes = gigaSpace.readMultiple(templateAttribute);
final Map<String, Object> attributesMap = new HashMap<String, Object>();
for (final InstanceCloudifyAttribute attribute : attributes) {
attributesMap.put(attribute.getInstanceId() + ":" + attribute.getKey(), attribute.getValue());
}
return attributesMap;
}
/**
* Gets an attribute value, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param attributeName
* The name (key) of the attribute to get.
* @return The attribute's value.
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}/{attributeName}",
method = RequestMethod.GET)
@ResponseBody
public Object getServiceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName,
@PathVariable final String attributeName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get attribute " + attributeName + " of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final ServiceCloudifyAttribute templateAttribute =
new ServiceCloudifyAttribute(applicationName, serviceName, attributeName, null);
// read the matching attribute from the space
final ServiceCloudifyAttribute valueEntry = gigaSpace.read(templateAttribute);
final Object value = valueEntry != null ? valueEntry.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Gets multiple attributes' values, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @return a Map containing the attributes' names (keys) and values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getServiceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get all attributes of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final ServiceCloudifyAttribute templateAttribute =
new ServiceCloudifyAttribute(applicationName, serviceName, null, null);
// read the matching multiple attributes from the space
final ServiceCloudifyAttribute[] attributes = gigaSpace.readMultiple(templateAttribute);
final Map<String, Object> attributesMap = new HashMap<String, Object>();
for (final ServiceCloudifyAttribute attribute : attributes) {
attributesMap.put(attribute.getKey(), attribute.getValue());
}
return attributesMap;
}
/**
* Gets an attribute value, scope: application attributes.
*
* @param applicationName
* The application name.
* @param attributeName
* The name (key) of the attribute to get.
* @return The attribute's value.
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}/{attributeName}", method = RequestMethod.GET)
@ResponseBody
public Object getApplicationAttribute(@PathVariable final String applicationName,
@PathVariable final String attributeName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get attribute " + attributeName + " of application " + applicationName);
}
final ApplicationCloudifyAttribute templateAttribute =
new ApplicationCloudifyAttribute(applicationName, attributeName, null);
// read the matching attribute from the space
final ApplicationCloudifyAttribute valueEntry = gigaSpace.read(templateAttribute);
final Object value = valueEntry != null ? valueEntry.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Gets multiple attributes' values, scope: application attributes.
*
* @param applicationName
* The application name.
* @return a Map containing the attributes' names (keys) and values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getApplicationAttributes(@PathVariable final String applicationName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get all attributes of application " + applicationName);
}
final ApplicationCloudifyAttribute templateAttribute =
new ApplicationCloudifyAttribute(applicationName, null, null);
// read the matching multiple attributes from the space
final ApplicationCloudifyAttribute[] attributes = gigaSpace.readMultiple(templateAttribute);
final Map<String, Object> attributesMap = new HashMap<String, Object>();
for (final ApplicationCloudifyAttribute attribute : attributes) {
attributesMap.put(attribute.getKey(), attribute.getValue());
}
return attributesMap;
}
/**
* Gets an attribute value, scope: global attributes.
*
* @param attributeName
* The name (key) of the attribute to get.
* @return The attribute's value.
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals/{attributeName}", method = RequestMethod.GET)
@ResponseBody
public Object getGlobalAttribute(@PathVariable final String attributeName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get global attribute " + attributeName);
}
final GlobalCloudifyAttribute templateAttribute = new GlobalCloudifyAttribute(attributeName, null);
// read the matching attribute from the space
final GlobalCloudifyAttribute valueEntry = gigaSpace.read(templateAttribute);
final Object value = valueEntry != null ? valueEntry.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Gets multiple attributes' values, scope: global attributes.
*
* @return a Map containing the attributes' names (keys) and values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}")
@PossibleResponseStatuses(responseStatuses = {
@PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getGlobalAttributes() {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to get all global attributes");
}
final GlobalCloudifyAttribute templateAttribute = new GlobalCloudifyAttribute();
// read the matching multiple attributes from the space
final GlobalCloudifyAttribute[] attributes = gigaSpace.readMultiple(templateAttribute);
final Map<String, Object> attributesMap = new HashMap<String, Object>();
for (final GlobalCloudifyAttribute attribute : attributes) {
attributesMap.put(attribute.getKey(), attribute.getValue());
}
return attributesMap;
}
/**
* Sets an attribute value, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @param attributeName
* The name of the attribute to get.
* @param attributeValue
* The value to set.
* @return The previous value.
*/
@JsonRequestExample(requestBody = "\"attributeValue\"")
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before changed)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}/{attributeName}",
method = RequestMethod.POST)
@ResponseBody
public Object setInstanceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final int instanceId,
@PathVariable final String attributeName, @RequestBody final Object attributeValue) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set attribute " + attributeName + " of instance number " + instanceId
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName + " to: " + attributeValue);
}
final InstanceCloudifyAttribute attribute =
new InstanceCloudifyAttribute(applicationName, serviceName, instanceId, attributeName, null);
// take (delete)
final InstanceCloudifyAttribute previousValue = gigaSpace.take(attribute);
// write
attribute.setValue(attributeValue);
gigaSpace.write(attribute);
final Object value = previousValue != null ? previousValue.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Sets multiple attributes' values, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @param attributesMap
* a Map containing the attributes' names (keys) and values to set.
* @return The status of the operation.
*/
@JsonRequestExample(requestBody =
"{\"attribute1Name\":\"attribute1Value\", \"attribute2Name\":\"attribute2Value\"}")
@JsonResponseExample(status = "success")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}",
method = RequestMethod.POST)
@ResponseBody
public Object setInstanceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final int instanceId,
@RequestBody final Map<String, Object> attributesMap) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set multiple attributes of instance number " + instanceId
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
writeAttributesToSpace(applicationName, serviceName, instanceId, attributesMap);
return successStatus();
}
/**
* Sets an attribute value, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param attributeName
* The name of the attribute to get.
* @param attributeValue
* The value to set.
* @return The previous value.
*/
@JsonRequestExample(requestBody = "\"attributeValue\"")
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before changed)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}/{attributeName}",
method = RequestMethod.POST)
@ResponseBody
public Object setServiceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final String attributeName,
@RequestBody final Object attributeValue) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set attribute " + attributeName
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName + " to: " + attributeValue);
}
final ServiceCloudifyAttribute attribute =
new ServiceCloudifyAttribute(applicationName, serviceName, attributeName, null);
// take (delete)
final ServiceCloudifyAttribute previousValue = gigaSpace.take(attribute);
// write
attribute.setValue(attributeValue);
gigaSpace.write(attribute);
final Object value = previousValue != null ? previousValue.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Sets multiple attributes' values, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param attributesMap
* a Map containing the attributes' names (keys) and values to set.
* @return A map of the previous values.
*/
@JsonRequestExample(requestBody =
"{\"attribute1Name\":\"attribute1Value\", \"attribute2Name\":\"attribute2Value\"}")
@JsonResponseExample(status = "success")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}", method = RequestMethod.POST)
@ResponseBody
public Object setServiceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName, @RequestBody final Map<String, Object> attributesMap) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set multiple attributes of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
writeAttributesToSpace(applicationName, serviceName, null, attributesMap);
return successStatus();
}
/**
* Sets an attribute value, scope: application attributes.
*
* @param applicationName
* The application name.
* @param attributeName
* The name of the attribute to get.
* @param attributeValue
* The value to set.
* @return The previous value.
*/
@JsonRequestExample(requestBody = "\"attributeValue\"")
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before changed)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}/{attributeName}", method = RequestMethod.POST)
@ResponseBody
public Object setApplicationAttribute(@PathVariable final String applicationName,
@PathVariable final String attributeName, @RequestBody final Object attributeValue) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set attribute " + attributeName
+ " of application " + applicationName + " to: " + attributeValue);
}
final ApplicationCloudifyAttribute attribute =
new ApplicationCloudifyAttribute(applicationName, attributeName, null);
// take (delete)
final ApplicationCloudifyAttribute previousValue = gigaSpace.take(attribute);
// write
attribute.setValue(attributeValue);
gigaSpace.write(attribute);
final Object value = previousValue != null ? previousValue.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Sets multiple attributes' values, scope: application attributes.
*
* @param applicationName
* The application name.
* @param attributesMap
* a Map containing the attributes' names (keys) and values to set.
* @return A map of the previous values.
*/
@JsonRequestExample(requestBody =
"{\"attribute1Name\":\"attribute1Value\", \"attribute2Name\":\"attribute2Value\"}")
@JsonResponseExample(status = "success")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}", method = RequestMethod.POST)
@ResponseBody
public Object setApplicationAttributes(@PathVariable final String applicationName,
@RequestBody final Map<String, Object> attributesMap) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set multiple attributes of application " + applicationName);
}
// write to space
writeAttributesToSpace(applicationName, null, null, attributesMap);
return successStatus();
}
private void writeAttributesToSpace(final String applicationName, final String serviceName,
final Integer instanceId, final Map<String, Object> attributesMap) {
final AbstractCloudifyAttribute[] attributesToWrite = new AbstractCloudifyAttribute[attributesMap.size()];
int i = 0;
for (final Entry<String, Object> attrEntry : attributesMap.entrySet()) {
final AbstractCloudifyAttribute newAttr = createCloudifyAttribute(applicationName,
serviceName, instanceId, attrEntry.getKey(), null);
gigaSpace.take(newAttr);
newAttr.setValue(attrEntry.getValue());
attributesToWrite[i++] = newAttr;
}
gigaSpace.writeMultiple(attributesToWrite, Lease.FOREVER, WriteModifiers.UPDATE_OR_WRITE);
}
private AbstractCloudifyAttribute createCloudifyAttribute(final String applicationName,
final String serviceName, final Integer instanceId, final String name, final Object value) {
if (applicationName == null) {
return new GlobalCloudifyAttribute(name, value);
}
if (serviceName == null) {
return new ApplicationCloudifyAttribute(applicationName, name, value);
}
if (instanceId == null) {
return new ServiceCloudifyAttribute(applicationName, serviceName, name, value);
}
return new InstanceCloudifyAttribute(applicationName, serviceName, instanceId, name, value);
}
/**
* Sets an attribute value, scope: global attributes.
*
* @param attributeName
* The name of the attribute to get.
* @param attributeValue
* The value to set.
* @return The previous value.
*/
@JsonRequestExample(requestBody = "\"attributeValue\"")
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before changed)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals/{attributeName}", method = RequestMethod.POST)
@ResponseBody
public Object setGlobalAttribute(@PathVariable final String attributeName,
@RequestBody final Object attributeValue) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set global attribute " + attributeName + " to: " + attributeValue);
}
final GlobalCloudifyAttribute attribute = new GlobalCloudifyAttribute(attributeName, null);
// take (delete)
final GlobalCloudifyAttribute previousValue = gigaSpace.take(attribute);
// write
attribute.setValue(attributeValue);
gigaSpace.write(attribute);
final Object value = previousValue != null ? previousValue.getValue() : null;
final Map<String, Object> mapResult = new HashMap<String, Object>();
mapResult.put(attributeName, value);
return mapResult;
}
/**
* Sets multiple attributes' values, scope: global attributes.
*
* @param attributesMap
* a Map containing the attributes' names (keys) and values to set.
* @return A map of the previous values.
*/
@JsonRequestExample(requestBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}")
@JsonResponseExample(status = "success")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals", method = RequestMethod.POST)
@ResponseBody
public Object setGlobalAttributes(@RequestBody final Map<String, Object> attributesMap) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to set multiple global attributes");
}
// write multiple
writeAttributesToSpace(null, null, null, attributesMap);
return successStatus();
}
/**
* Deletes an attribute value, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @param attributeName
* The name of the attribute to get.
* @return The previous value.
* @throws RestErrorException .
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}/{attributeName}",
method = RequestMethod.DELETE)
@ResponseBody
public Object deleteInstanceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final int instanceId,
@PathVariable final String attributeName) throws RestErrorException {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete attribute " + attributeName + " of instance number " + instanceId
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final InstanceCloudifyAttribute attribute = new InstanceCloudifyAttribute(applicationName, serviceName,
instanceId, attributeName, null);
// take (delete)
final InstanceCloudifyAttribute previousValue = gigaSpace.take(attribute);
final Map<String, Object> mapResult = createDeleteAttributeResponseMap(attributeName, previousValue);
return mapResult;
}
/**
* Deletes multiple attributes, scope: instance attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param instanceId
* The service instance id.
* @return A map of the previous values.
*/
@JsonResponseExample(status = "success", responseBody =
"{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}",
comments = "attribute1Value and attribute2Value are the previous values (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "instances/{applicationName}/{serviceName}/{instanceId}",
method = RequestMethod.DELETE)
@ResponseBody
public Object deleteInstanceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final int instanceId) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete multiple attributes of instance number " + instanceId
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final InstanceCloudifyAttribute attribute =
new InstanceCloudifyAttribute(applicationName, serviceName, instanceId, null, null);
// take (delete) multiple
final InstanceCloudifyAttribute[] previousAttributesArr = gigaSpace.takeMultiple(attribute);
final Map<String, Object> previousAttributesMap = new HashMap<String, Object>();
for (final InstanceCloudifyAttribute previousAttr : previousAttributesArr) {
previousAttributesMap.put(previousAttr.getKey(), previousAttr.getValue());
}
return previousAttributesMap;
}
/**
* Deletes an attribute value, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @param attributeName
* The name of the attribute to get.
* @return The previous value.
* @throws RestErrorException .
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}/{attributeName}",
method = RequestMethod.DELETE)
@ResponseBody
public Object deleteServiceAttribute(@PathVariable final String applicationName,
@PathVariable final String serviceName, @PathVariable final String attributeName)
throws RestErrorException {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete attribute " + attributeName
+ " of service " + ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final ServiceCloudifyAttribute attribute =
new ServiceCloudifyAttribute(applicationName, serviceName, attributeName, null);
// take (delete)
final ServiceCloudifyAttribute previousValue = gigaSpace.take(attribute);
final Map<String, Object> mapResult = createDeleteAttributeResponseMap(attributeName, previousValue);
return mapResult;
}
/**
* Deletes multiple attributes, scope: service attributes.
*
* @param applicationName
* The application name.
* @param serviceName
* The service name.
* @return A map of the previous values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}",
comments = "attribute1Value and attribute2Value are the previous values (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "services/{applicationName}/{serviceName}", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteServiceAttributes(@PathVariable final String applicationName,
@PathVariable final String serviceName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete multiple attributes of service "
+ ServiceUtils.getAbsolutePUName(applicationName, serviceName)
+ " of application " + applicationName);
}
final ServiceCloudifyAttribute attribute =
new ServiceCloudifyAttribute(applicationName, serviceName, null, null);
// take (delete) multiple
final ServiceCloudifyAttribute[] previousAttributesArr = gigaSpace.takeMultiple(attribute);
final Map<String, Object> previousAttributesMap = new HashMap<String, Object>();
for (final ServiceCloudifyAttribute previousAttr : previousAttributesArr) {
previousAttributesMap.put(previousAttr.getKey(), previousAttr.getValue());
}
return previousAttributesMap;
}
/**
* Deletes an attribute value, scope: application attributes.
*
* @param applicationName
* The application name.
* @param attributeName
* The name of the attribute to get.
* @return The previous value.
* @throws RestErrorException .
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}/{attributeName}", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteApplicationAttribute(@PathVariable final String applicationName,
@PathVariable final String attributeName) throws RestErrorException {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete attribute " + attributeName
+ " of application " + applicationName);
}
final ApplicationCloudifyAttribute attribute =
new ApplicationCloudifyAttribute(applicationName, attributeName, null);
// take (delete)
final ApplicationCloudifyAttribute previousValue = gigaSpace.take(attribute);
final Map<String, Object> mapResult = createDeleteAttributeResponseMap(attributeName, previousValue);
return mapResult;
}
/**
* Deletes multiple attributes, scope: application attributes.
*
* @param applicationName
* The application name.
* @return A map of the previous values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}",
comments = "attribute1Value and attribute2Value are the previous values (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "applications/{applicationName}", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteApplicationAttributes(@PathVariable final String applicationName) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete multiple attributes of application " + applicationName);
}
final ApplicationCloudifyAttribute attribute = new ApplicationCloudifyAttribute(applicationName, null, null);
// take (delete) multiple
final ApplicationCloudifyAttribute[] previousAttributesArr = gigaSpace.takeMultiple(attribute);
final Map<String, Object> previousAttributesMap = new HashMap<String, Object>();
for (final ApplicationCloudifyAttribute previousAttr : previousAttributesArr) {
previousAttributesMap.put(previousAttr.getKey(), previousAttr.getValue());
}
return previousAttributesMap;
}
/**
* Deletes an attribute, scope: global attributes.
*
* @param attributeName
* The name of the attribute to delete.
* @return The previous value.
* @throws RestErrorException .
*/
@JsonResponseExample(status = "success", responseBody = "{\"attributeName\":\"attributeValue\"}",
comments = "attributeValue is the previous value (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals/{attributeName}", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteGlobalAttribute(@PathVariable final String attributeName) throws RestErrorException {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete global attribute: " + attributeName);
}
final GlobalCloudifyAttribute attribute = new GlobalCloudifyAttribute(attributeName, null);
// take (delete)
final GlobalCloudifyAttribute previousValue = gigaSpace.take(attribute);
final Map<String, Object> mapResult = createDeleteAttributeResponseMap(attributeName, previousValue);
return mapResult;
}
private Map<String, Object> createDeleteAttributeResponseMap(final String attributeName,
final AbstractCloudifyAttribute previousValue) throws RestErrorException {
final boolean found = (previousValue != null);
if (found) {
final Map<String, Object> mapResult = new HashMap<String, Object>();
final Object value = previousValue.getValue();
mapResult.put(attributeName, value);
return mapResult;
} else {
throw new RestErrorException("attribute_not_found", attributeName);
}
}
/**
* Deletes multiple attributes, scope: global attributes.
*
* @return A list of the previous values.
*/
@JsonResponseExample(status = "success",
responseBody = "{\"attribute1Name\":\"attribute1Value\",\"attribute2Name\":\"attribute2Value\"}",
comments = "attribute1Value and attribute2Value are the previous values (before deleted)")
@PossibleResponseStatuses(responseStatuses = { @PossibleResponseStatus(code = HTTP_OK, description = "success") })
@RequestMapping(value = "globals", method = RequestMethod.DELETE)
@ResponseBody
public Object deleteGlobalAttributes() {
if (logger.isLoggable(Level.FINER)) {
logger.finer("received request to delete multiple global attributes");
}
final GlobalCloudifyAttribute attribute = new GlobalCloudifyAttribute();
// take (delete) multiple
final GlobalCloudifyAttribute[] previousAttributesArr = gigaSpace.takeMultiple(attribute);
final Map<String, Object> previousAttributesMap = new HashMap<String, Object>();
for (final GlobalCloudifyAttribute previousAttr : previousAttributesArr) {
previousAttributesMap.put(previousAttr.getKey(), previousAttr.getValue());
}
return previousAttributesMap;
}
}