| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| package com.cloud.bridge.service; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.net.URLEncoder; |
| import java.security.KeyStore; |
| import java.security.SignatureException; |
| import java.security.cert.Certificate; |
| import java.security.cert.CertificateFactory; |
| import java.sql.SQLException; |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.UUID; |
| |
| import javax.inject.Inject; |
| import javax.servlet.ServletConfig; |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.xml.stream.XMLOutputFactory; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamWriter; |
| |
| import org.apache.axiom.om.OMAbstractFactory; |
| import org.apache.axiom.om.OMFactory; |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.databinding.ADBBean; |
| import org.apache.axis2.databinding.ADBException; |
| import org.apache.axis2.databinding.utils.writer.MTOMAwareXMLSerializer; |
| import org.apache.commons.codec.binary.Base64; |
| import org.apache.log4j.Logger; |
| import org.springframework.stereotype.Component; |
| import org.springframework.web.context.support.SpringBeanAutowiringSupport; |
| |
| import com.amazon.ec2.AllocateAddressResponse; |
| import com.amazon.ec2.AssociateAddressResponse; |
| import com.amazon.ec2.AttachVolumeResponse; |
| import com.amazon.ec2.AuthorizeSecurityGroupIngressResponse; |
| import com.amazon.ec2.CreateImageResponse; |
| import com.amazon.ec2.CreateKeyPairResponse; |
| import com.amazon.ec2.CreateSecurityGroupResponse; |
| import com.amazon.ec2.CreateSnapshotResponse; |
| import com.amazon.ec2.CreateTagsResponse; |
| import com.amazon.ec2.CreateVolumeResponse; |
| import com.amazon.ec2.DeleteKeyPairResponse; |
| import com.amazon.ec2.DeleteSecurityGroupResponse; |
| import com.amazon.ec2.DeleteSnapshotResponse; |
| import com.amazon.ec2.DeleteTagsResponse; |
| import com.amazon.ec2.DeleteVolumeResponse; |
| import com.amazon.ec2.DeregisterImageResponse; |
| import com.amazon.ec2.DescribeAvailabilityZonesResponse; |
| import com.amazon.ec2.DescribeImageAttributeResponse; |
| import com.amazon.ec2.DescribeImagesResponse; |
| import com.amazon.ec2.DescribeInstanceAttributeResponse; |
| import com.amazon.ec2.DescribeInstancesResponse; |
| import com.amazon.ec2.DescribeKeyPairsResponse; |
| import com.amazon.ec2.DescribeSecurityGroupsResponse; |
| import com.amazon.ec2.DescribeSnapshotsResponse; |
| import com.amazon.ec2.DescribeTagsResponse; |
| import com.amazon.ec2.DescribeVolumesResponse; |
| import com.amazon.ec2.DetachVolumeResponse; |
| import com.amazon.ec2.DisassociateAddressResponse; |
| import com.amazon.ec2.GetPasswordDataResponse; |
| import com.amazon.ec2.ImportKeyPairResponse; |
| import com.amazon.ec2.ModifyImageAttributeResponse; |
| import com.amazon.ec2.ModifyInstanceAttributeResponse; |
| import com.amazon.ec2.RebootInstancesResponse; |
| import com.amazon.ec2.RegisterImageResponse; |
| import com.amazon.ec2.ReleaseAddressResponse; |
| import com.amazon.ec2.ResetImageAttributeResponse; |
| import com.amazon.ec2.RevokeSecurityGroupIngressResponse; |
| import com.amazon.ec2.RunInstancesResponse; |
| import com.amazon.ec2.StartInstancesResponse; |
| import com.amazon.ec2.StopInstancesResponse; |
| import com.amazon.ec2.TerminateInstancesResponse; |
| import com.cloud.bridge.model.UserCredentialsVO; |
| import com.cloud.bridge.persist.dao.CloudStackUserDaoImpl; |
| import com.cloud.bridge.persist.dao.OfferingDaoImpl; |
| import com.cloud.bridge.persist.dao.UserCredentialsDaoImpl; |
| import com.cloud.bridge.service.controller.s3.ServiceProvider; |
| import com.cloud.bridge.service.core.ec2.EC2AddressFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2AssociateAddress; |
| import com.cloud.bridge.service.core.ec2.EC2AuthorizeRevokeSecurityGroup; |
| import com.cloud.bridge.service.core.ec2.EC2AvailabilityZonesFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2CreateImage; |
| import com.cloud.bridge.service.core.ec2.EC2CreateKeyPair; |
| import com.cloud.bridge.service.core.ec2.EC2CreateVolume; |
| import com.cloud.bridge.service.core.ec2.EC2DeleteKeyPair; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeAddresses; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeAvailabilityZones; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeImageAttribute; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeImages; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeInstances; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeSnapshots; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeTags; |
| import com.cloud.bridge.service.core.ec2.EC2DescribeVolumes; |
| import com.cloud.bridge.service.core.ec2.EC2DisassociateAddress; |
| import com.cloud.bridge.service.core.ec2.EC2Engine; |
| import com.cloud.bridge.service.core.ec2.EC2Filter; |
| import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2Image; |
| import com.cloud.bridge.service.core.ec2.EC2ImageFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute; |
| import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission; |
| import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair; |
| import com.cloud.bridge.service.core.ec2.EC2InstanceFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2IpPermission; |
| import com.cloud.bridge.service.core.ec2.EC2KeyPairFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2ModifyImageAttribute; |
| import com.cloud.bridge.service.core.ec2.EC2ModifyInstanceAttribute; |
| import com.cloud.bridge.service.core.ec2.EC2RebootInstances; |
| import com.cloud.bridge.service.core.ec2.EC2RegisterImage; |
| import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress; |
| import com.cloud.bridge.service.core.ec2.EC2RunInstances; |
| import com.cloud.bridge.service.core.ec2.EC2SecurityGroup; |
| import com.cloud.bridge.service.core.ec2.EC2SnapshotFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2StartInstances; |
| import com.cloud.bridge.service.core.ec2.EC2StopInstances; |
| import com.cloud.bridge.service.core.ec2.EC2Tags; |
| import com.cloud.bridge.service.core.ec2.EC2TagsFilterSet; |
| import com.cloud.bridge.service.core.ec2.EC2Volume; |
| import com.cloud.bridge.service.core.ec2.EC2VolumeFilterSet; |
| import com.cloud.bridge.service.exception.EC2ServiceException; |
| import com.cloud.bridge.service.exception.EC2ServiceException.ClientError; |
| import com.cloud.bridge.service.exception.NoSuchObjectException; |
| import com.cloud.bridge.service.exception.PermissionDeniedException; |
| import com.cloud.bridge.util.AuthenticationUtils; |
| import com.cloud.bridge.util.ConfigurationHelper; |
| import com.cloud.bridge.util.EC2RestAuth; |
| import com.cloud.stack.models.CloudStackAccount; |
| import com.cloud.utils.db.Transaction; |
| import com.cloud.utils.db.TransactionLegacy; |
| |
| @Component("EC2RestServlet") |
| public class EC2RestServlet extends HttpServlet { |
| |
| private static final long serialVersionUID = -6168996266762804888L; |
| @Inject |
| UserCredentialsDaoImpl ucDao; |
| @Inject |
| OfferingDaoImpl ofDao; |
| @Inject |
| CloudStackUserDaoImpl userDao; |
| |
| public static final Logger logger = Logger.getLogger(EC2RestServlet.class); |
| |
| private final OMFactory factory = OMAbstractFactory.getOMFactory(); |
| private final XMLOutputFactory xmlOutFactory = XMLOutputFactory.newInstance(); |
| |
| private String pathToKeystore = null; |
| private String keystorePassword = null; |
| private String wsdlVersion = null; |
| private String version = null; |
| |
| boolean debug = true; |
| |
| public EC2RestServlet() { |
| } |
| |
| /** |
| * We build the path to where the keystore holding the WS-Security X509 certificates |
| * are stored. |
| */ |
| @Override |
| public void init(ServletConfig config) throws ServletException { |
| SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); |
| |
| File propertiesFile = ConfigurationHelper.findConfigurationFile("ec2-service.properties"); |
| Properties EC2Prop = null; |
| |
| if (null != propertiesFile) { |
| logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath()); |
| EC2Prop = new Properties(); |
| try { |
| EC2Prop.load(new FileInputStream(propertiesFile)); |
| } catch (FileNotFoundException e) { |
| logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e); |
| } catch (IOException e) { |
| logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e); |
| } |
| String keystore = EC2Prop.getProperty("keystore"); |
| keystorePassword = EC2Prop.getProperty("keystorePass"); |
| wsdlVersion = EC2Prop.getProperty("WSDLVersion", "2012-08-15"); |
| version = EC2Prop.getProperty("cloudbridgeVersion", "UNKNOWN VERSION"); |
| |
| String installedPath = System.getenv("CATALINA_HOME"); |
| if (installedPath == null) |
| installedPath = System.getenv("CATALINA_BASE"); |
| if (installedPath == null) |
| installedPath = System.getProperty("catalina.home"); |
| String webappPath = config.getServletContext().getRealPath("/"); |
| //pathToKeystore = new String( installedPath + File.separator + "webapps" + File.separator + webappName + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + keystore ); |
| pathToKeystore = new String(webappPath + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + keystore); |
| } |
| } |
| |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) { |
| doGetOrPost(req, resp); |
| } |
| |
| @Override |
| protected void doPost(HttpServletRequest req, HttpServletResponse resp) { |
| doGetOrPost(req, resp); |
| } |
| |
| protected void doGetOrPost(HttpServletRequest request, HttpServletResponse response) { |
| |
| if (debug) { |
| System.out.println("EC2RestServlet.doGetOrPost: javax.servlet.forward.request_uri: " + request.getAttribute("javax.servlet.forward.request_uri")); |
| System.out.println("EC2RestServlet.doGetOrPost: javax.servlet.forward.context_path: " + request.getAttribute("javax.servlet.forward.context_path")); |
| System.out.println("EC2RestServlet.doGetOrPost: javax.servlet.forward.servlet_path: " + request.getAttribute("javax.servlet.forward.servlet_path")); |
| System.out.println("EC2RestServlet.doGetOrPost: javax.servlet.forward.path_info: " + request.getAttribute("javax.servlet.forward.path_info")); |
| System.out.println("EC2RestServlet.doGetOrPost: javax.servlet.forward.query_string: " + request.getAttribute("javax.servlet.forward.query_string")); |
| |
| } |
| |
| String action = request.getParameter("Action"); |
| logRequest(request); |
| |
| // -> unauthenticated calls, should still be done over HTTPS |
| if (action.equalsIgnoreCase("SetUserKeys")) { |
| setUserKeys(request, response); |
| return; |
| } |
| |
| if (action.equalsIgnoreCase("CloudEC2Version")) { |
| cloudEC2Version(request, response); |
| return; |
| } |
| |
| // -> authenticated calls |
| try { |
| if (!authenticateRequest(request, response)) |
| return; |
| |
| if (action.equalsIgnoreCase("AllocateAddress")) |
| allocateAddress(request, response); |
| else if (action.equalsIgnoreCase("AssociateAddress")) |
| associateAddress(request, response); |
| else if (action.equalsIgnoreCase("AttachVolume")) |
| attachVolume(request, response); |
| else if (action.equalsIgnoreCase("AuthorizeSecurityGroupIngress")) |
| authorizeSecurityGroupIngress(request, response); |
| else if (action.equalsIgnoreCase("CreateImage")) |
| createImage(request, response); |
| else if (action.equalsIgnoreCase("CreateSecurityGroup")) |
| createSecurityGroup(request, response); |
| else if (action.equalsIgnoreCase("CreateSnapshot")) |
| createSnapshot(request, response); |
| else if (action.equalsIgnoreCase("CreateVolume")) |
| createVolume(request, response); |
| else if (action.equalsIgnoreCase("DeleteSecurityGroup")) |
| deleteSecurityGroup(request, response); |
| else if (action.equalsIgnoreCase("DeleteSnapshot")) |
| deleteSnapshot(request, response); |
| else if (action.equalsIgnoreCase("DeleteVolume")) |
| deleteVolume(request, response); |
| else if (action.equalsIgnoreCase("DeregisterImage")) |
| deregisterImage(request, response); |
| else if (action.equalsIgnoreCase("DescribeAddresses")) |
| describeAddresses(request, response); |
| else if (action.equalsIgnoreCase("DescribeAvailabilityZones")) |
| describeAvailabilityZones(request, response); |
| else if (action.equalsIgnoreCase("DescribeImageAttribute")) |
| describeImageAttribute(request, response); |
| else if (action.equalsIgnoreCase("DescribeImages")) |
| describeImages(request, response); |
| else if (action.equalsIgnoreCase("DescribeInstanceAttribute")) |
| describeInstanceAttribute(request, response); |
| else if (action.equalsIgnoreCase("DescribeInstances")) |
| describeInstances(request, response); |
| else if (action.equalsIgnoreCase("DescribeSecurityGroups")) |
| describeSecurityGroups(request, response); |
| else if (action.equalsIgnoreCase("DescribeSnapshots")) |
| describeSnapshots(request, response); |
| else if (action.equalsIgnoreCase("DescribeVolumes")) |
| describeVolumes(request, response); |
| else if (action.equalsIgnoreCase("DetachVolume")) |
| detachVolume(request, response); |
| else if (action.equalsIgnoreCase("DisassociateAddress")) |
| disassociateAddress(request, response); |
| else if (action.equalsIgnoreCase("ModifyImageAttribute")) |
| modifyImageAttribute(request, response); |
| else if (action.equalsIgnoreCase("ModifyInstanceAttribute")) |
| modifyInstanceAttribute(request, response); |
| else if (action.equalsIgnoreCase("RebootInstances")) |
| rebootInstances(request, response); |
| else if (action.equalsIgnoreCase("RegisterImage")) |
| registerImage(request, response); |
| else if (action.equalsIgnoreCase("ReleaseAddress")) |
| releaseAddress(request, response); |
| else if (action.equalsIgnoreCase("ResetImageAttribute")) |
| resetImageAttribute(request, response); |
| else if (action.equalsIgnoreCase("RevokeSecurityGroupIngress")) |
| revokeSecurityGroupIngress(request, response); |
| else if (action.equalsIgnoreCase("RunInstances")) |
| runInstances(request, response); |
| else if (action.equalsIgnoreCase("StartInstances")) |
| startInstances(request, response); |
| else if (action.equalsIgnoreCase("StopInstances")) |
| stopInstances(request, response); |
| else if (action.equalsIgnoreCase("TerminateInstances")) |
| terminateInstances(request, response); |
| else if (action.equalsIgnoreCase("SetCertificate")) |
| setCertificate(request, response); |
| else if (action.equalsIgnoreCase("DeleteCertificate")) |
| deleteCertificate(request, response); |
| else if (action.equalsIgnoreCase("SetOfferMapping")) |
| setOfferMapping(request, response); |
| else if (action.equalsIgnoreCase("DeleteOfferMapping")) |
| deleteOfferMapping(request, response); |
| else if (action.equalsIgnoreCase("CreateKeyPair")) |
| createKeyPair(request, response); |
| else if (action.equalsIgnoreCase("ImportKeyPair")) |
| importKeyPair(request, response); |
| else if (action.equalsIgnoreCase("DeleteKeyPair")) |
| deleteKeyPair(request, response); |
| else if (action.equalsIgnoreCase("DescribeKeyPairs")) |
| describeKeyPairs(request, response); |
| else if (action.equalsIgnoreCase("CreateTags")) |
| createTags(request, response); |
| else if (action.equalsIgnoreCase("DeleteTags")) |
| deleteTags(request, response); |
| else if (action.equalsIgnoreCase("DescribeTags")) |
| describeTags(request, response); |
| else if (action.equalsIgnoreCase("GetPasswordData")) |
| getPasswordData(request, response); |
| else { |
| logger.error("Unsupported action " + action); |
| throw new EC2ServiceException(ClientError.Unsupported, "This operation is not available"); |
| } |
| |
| } catch (EC2ServiceException e) { |
| response.setStatus(e.getErrorCode()); |
| |
| if (e.getCause() != null && e.getCause() instanceof AxisFault) { |
| String errorCode = ((AxisFault)e.getCause()).getFaultCode().getLocalPart(); |
| if (errorCode.startsWith("Client.")) // only in a SOAP API client error code is prefixed with Client. |
| errorCode = errorCode.split("Client.")[1]; |
| else if (errorCode.startsWith("Server.")) // only in a SOAP API server error code is prefixed with Server. |
| errorCode = errorCode.split("Server.")[1]; |
| faultResponse(response, errorCode, e.getMessage()); |
| } else { |
| logger.error("EC2ServiceException: " + e.getMessage(), e); |
| endResponse(response, e.toString()); |
| } |
| } catch (PermissionDeniedException e) { |
| logger.error("Unexpected exception: " + e.getMessage(), e); |
| response.setStatus(403); |
| endResponse(response, "Access denied"); |
| |
| } catch (Exception e) { |
| logger.error("Unexpected exception: " + e.getMessage(), e); |
| response.setStatus(500); |
| endResponse(response, e.toString()); |
| |
| } finally { |
| try { |
| response.flushBuffer(); |
| } catch (IOException e) { |
| logger.error("Unexpected exception " + e.getMessage(), e); |
| } |
| } |
| } |
| |
| /** |
| * Provide an easy way to determine the version of the implementation running. |
| * |
| * This is an unauthenticated REST call. |
| */ |
| private void cloudEC2Version(HttpServletRequest request, HttpServletResponse response) { |
| String version_response = new String("<?xml version=\"1.0\" encoding=\"utf-8\"?><CloudEC2Version>" + version + "</CloudEC2Version>"); |
| response.setStatus(200); |
| endResponse(response, version_response); |
| } |
| |
| /** |
| * This request registers the Cloud.com account holder to the EC2 service. The Cloud.com |
| * account holder saves his API access and secret keys with the EC2 service so that |
| * the EC2 service can make Cloud.com API calls on his behalf. The given API access |
| * and secret key are saved into the "usercredentials" database table. |
| * |
| * This is an unauthenticated REST call. The only required parameters are 'accesskey' and |
| * 'secretkey'. |
| * |
| * To verify that the given keys represent an existing account they are used to execute the |
| * Cloud.com's listAccounts API function. If the keys do not represent a valid account the |
| * listAccounts function will fail. |
| * |
| * A user can call this REST function any number of times, on each call the Cloud.com secret |
| * key is simply over writes any previously stored value. |
| * |
| * As with all REST calls HTTPS should be used to ensure their security. |
| */ |
| private void setUserKeys(HttpServletRequest request, HttpServletResponse response) { |
| String[] accessKey = null; |
| String[] secretKey = null; |
| TransactionLegacy txn = null; |
| try { |
| // -> all these parameters are required |
| accessKey = request.getParameterValues("accesskey"); |
| if (null == accessKey || 0 == accessKey.length) { |
| response.sendError(530, "Missing accesskey parameter"); |
| return; |
| } |
| |
| secretKey = request.getParameterValues("secretkey"); |
| if (null == secretKey || 0 == secretKey.length) { |
| response.sendError(530, "Missing secretkey parameter"); |
| return; |
| } |
| } catch (Exception e) { |
| logger.error("SetUserKeys exception " + e.getMessage(), e); |
| response.setStatus(500); |
| endResponse(response, "SetUserKeys exception " + e.getMessage()); |
| return; |
| } |
| try { |
| txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); |
| txn.start(); |
| // -> use the keys to see if the account actually exists |
| ServiceProvider.getInstance().getEC2Engine().validateAccount(accessKey[0], secretKey[0]); |
| UserCredentialsVO user = new UserCredentialsVO(accessKey[0], secretKey[0]); |
| ucDao.persist(user); |
| txn.commit(); |
| } catch (Exception e) { |
| logger.error("SetUserKeys " + e.getMessage(), e); |
| response.setStatus(401); |
| endResponse(response, e.toString()); |
| txn.close(); |
| return; |
| } |
| response.setStatus(200); |
| endResponse(response, "User keys set successfully"); |
| } |
| |
| /** |
| * The SOAP API for EC2 uses WS-Security to sign all client requests. This requires that |
| * the client have a public/private key pair and the public key defined by a X509 certificate. |
| * Thus in order for a Cloud.com account holder to use the EC2's SOAP API he must register |
| * his X509 certificate with the EC2 service. This function allows the Cloud.com account |
| * holder to "load" his X509 certificate into the service. Note, that the SetUserKeys REST |
| * function must be called before this call. |
| * |
| * This is an authenticated REST call and as such must contain all the required REST parameters |
| * including: Signature, Timestamp, Expires, etc. The signature is calculated using the |
| * Cloud.com account holder's API access and secret keys and the Amazon defined EC2 signature |
| * algorithm. |
| * |
| * A user can call this REST function any number of times, on each call the X509 certificate |
| * simply over writes any previously stored value. |
| */ |
| private void setCertificate(HttpServletRequest request, HttpServletResponse response) throws Exception { |
| TransactionLegacy txn = null; |
| try { |
| // [A] Pull the cert and cloud AccessKey from the request |
| String[] certificate = request.getParameterValues("cert"); |
| if (null == certificate || 0 == certificate.length) { |
| response.sendError(530, "Missing cert parameter"); |
| return; |
| } |
| // logger.debug( "SetCertificate cert: [" + certificate[0] + "]" ); |
| |
| String[] accessKey = request.getParameterValues("AWSAccessKeyId"); |
| if (null == accessKey || 0 == accessKey.length) { |
| response.sendError(530, "Missing AWSAccessKeyId parameter"); |
| return; |
| } |
| |
| // [B] Open our keystore |
| FileInputStream fsIn = new FileInputStream(pathToKeystore); |
| KeyStore certStore = KeyStore.getInstance("JKS"); |
| certStore.load(fsIn, keystorePassword.toCharArray()); |
| |
| // -> use the Cloud API key to save the cert in the keystore |
| // -> write the cert into the keystore on disk |
| Certificate userCert = null; |
| CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
| |
| ByteArrayInputStream bs = new ByteArrayInputStream(certificate[0].getBytes()); |
| while (bs.available() > 0) |
| userCert = cf.generateCertificate(bs); |
| certStore.setCertificateEntry(accessKey[0], userCert); |
| |
| FileOutputStream fsOut = new FileOutputStream(pathToKeystore); |
| certStore.store(fsOut, keystorePassword.toCharArray()); |
| |
| // [C] Associate the cert's uniqueId with the Cloud API keys |
| String uniqueId = AuthenticationUtils.X509CertUniqueId(userCert); |
| logger.debug("SetCertificate, uniqueId: " + uniqueId); |
| txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); |
| txn.start(); |
| UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); |
| user.setCertUniqueId(uniqueId); |
| ucDao.update(user.getId(), user); |
| response.setStatus(200); |
| endResponse(response, "User certificate set successfully"); |
| txn.commit(); |
| |
| } catch (NoSuchObjectException e) { |
| logger.error("SetCertificate exception " + e.getMessage(), e); |
| response.sendError(404, "SetCertificate exception " + e.getMessage()); |
| |
| } catch (Exception e) { |
| logger.error("SetCertificate exception " + e.getMessage(), e); |
| response.sendError(500, "SetCertificate exception " + e.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| |
| } |
| |
| /** |
| * The SOAP API for EC2 uses WS-Security to sign all client requests. This requires that |
| * the client have a public/private key pair and the public key defined by a X509 certificate. |
| * This REST call allows a Cloud.com account holder to remove a previouly "loaded" X509 |
| * certificate out of the EC2 service. |
| * |
| * This is an unauthenticated REST call and as such must contain all the required REST parameters |
| * including: Signature, Timestamp, Expires, etc. The signature is calculated using the |
| * Cloud.com account holder's API access and secret keys and the Amazon defined EC2 signature |
| * algorithm. |
| */ |
| private void deleteCertificate(HttpServletRequest request, HttpServletResponse response) throws Exception { |
| TransactionLegacy txn = null; |
| try { |
| String[] accessKey = request.getParameterValues("AWSAccessKeyId"); |
| if (null == accessKey || 0 == accessKey.length) { |
| response.sendError(530, "Missing AWSAccessKeyId parameter"); |
| return; |
| } |
| |
| // -> delete the specified entry and save back to disk |
| FileInputStream fsIn = new FileInputStream(pathToKeystore); |
| KeyStore certStore = KeyStore.getInstance("JKS"); |
| certStore.load(fsIn, keystorePassword.toCharArray()); |
| |
| if (certStore.containsAlias(accessKey[0])) { |
| certStore.deleteEntry(accessKey[0]); |
| FileOutputStream fsOut = new FileOutputStream(pathToKeystore); |
| certStore.store(fsOut, keystorePassword.toCharArray()); |
| |
| // -> dis-associate the cert's uniqueId with the Cloud API keys |
| /* UserCredentialsDao credentialDao = new UserCredentialsDao(); |
| credentialDao.setCertificateId( accessKey[0], null ); |
| |
| */txn = TransactionLegacy.open(TransactionLegacy.AWSAPI_DB); |
| UserCredentialsVO user = ucDao.getByAccessKey(accessKey[0]); |
| user.setCertUniqueId(null); |
| ucDao.update(user.getId(), user); |
| response.setStatus(200); |
| endResponse(response, "User certificate deleted successfully"); |
| txn.commit(); |
| } else |
| response.setStatus(404); |
| |
| } catch (NoSuchObjectException e) { |
| logger.error("SetCertificate exception " + e.getMessage(), e); |
| response.sendError(404, "SetCertificate exception " + e.getMessage()); |
| |
| } catch (Exception e) { |
| logger.error("DeleteCertificate exception " + e.getMessage(), e); |
| response.sendError(500, "DeleteCertificate exception " + e.getMessage()); |
| } finally { |
| txn.close(); |
| } |
| } |
| |
| /** |
| * Allow the caller to define the mapping between the Amazon instance type strings |
| * (e.g., m1.small, cc1.4xlarge) and the cloudstack service offering ids. Setting |
| * an existing mapping just over writes the prevous values. |
| */ |
| private void setOfferMapping(HttpServletRequest request, HttpServletResponse response) { |
| String amazonOffer = null; |
| String cloudOffer = null; |
| |
| try { |
| // -> all these parameters are required |
| amazonOffer = request.getParameter("amazonoffer"); |
| if (null == amazonOffer) { |
| response.sendError(530, "Missing amazonoffer parameter"); |
| return; |
| } |
| |
| cloudOffer = request.getParameter("cloudoffer"); |
| if (null == cloudOffer) { |
| response.sendError(530, "Missing cloudoffer parameter"); |
| return; |
| } |
| } catch (Exception e) { |
| logger.error("SetOfferMapping exception " + e.getMessage(), e); |
| response.setStatus(500); |
| endResponse(response, "SetOfferMapping exception " + e.getMessage()); |
| return; |
| } |
| |
| // validate account is admin level |
| try { |
| CloudStackAccount currentAccount = ServiceProvider.getInstance().getEC2Engine().getCurrentAccount(); |
| |
| if (currentAccount.getAccountType() != 1) { |
| logger.debug("SetOfferMapping called by non-admin user!"); |
| response.setStatus(500); |
| endResponse(response, "Permission denied for non-admin user to setOfferMapping!"); |
| return; |
| } |
| } catch (Exception e) { |
| logger.error("SetOfferMapping " + e.getMessage(), e); |
| response.setStatus(401); |
| endResponse(response, e.toString()); |
| return; |
| } |
| |
| try { |
| |
| ofDao.setOfferMapping(amazonOffer, cloudOffer); |
| |
| } catch (Exception e) { |
| logger.error("SetOfferMapping " + e.getMessage(), e); |
| response.setStatus(401); |
| endResponse(response, e.toString()); |
| return; |
| } |
| response.setStatus(200); |
| endResponse(response, "offering mapping set successfully"); |
| } |
| |
| private void deleteOfferMapping(HttpServletRequest request, HttpServletResponse response) { |
| String amazonOffer = null; |
| |
| try { |
| // -> all these parameters are required |
| amazonOffer = request.getParameter("amazonoffer"); |
| if (null == amazonOffer) { |
| response.sendError(530, "Missing amazonoffer parameter"); |
| return; |
| } |
| |
| } catch (Exception e) { |
| logger.error("DeleteOfferMapping exception " + e.getMessage(), e); |
| response.setStatus(500); |
| endResponse(response, "DeleteOfferMapping exception " + e.getMessage()); |
| return; |
| } |
| |
| // validate account is admin level |
| try { |
| CloudStackAccount currentAccount = ServiceProvider.getInstance().getEC2Engine().getCurrentAccount(); |
| |
| if (currentAccount.getAccountType() != 1) { |
| logger.debug("deleteOfferMapping called by non-admin user!"); |
| response.setStatus(500); |
| endResponse(response, "Permission denied for non-admin user to deleteOfferMapping!"); |
| return; |
| } |
| } catch (Exception e) { |
| logger.error("deleteOfferMapping " + e.getMessage(), e); |
| response.setStatus(401); |
| endResponse(response, e.toString()); |
| return; |
| } |
| |
| try { |
| ofDao.deleteOfferMapping(amazonOffer); |
| } catch (Exception e) { |
| logger.error("DeleteOfferMapping " + e.getMessage(), e); |
| response.setStatus(401); |
| endResponse(response, e.toString()); |
| return; |
| } |
| response.setStatus(200); |
| endResponse(response, "offering mapping deleted successfully"); |
| } |
| |
| /** |
| * The approach taken here is to map these REST calls into the same objects used |
| * to implement the matching SOAP requests (e.g., AttachVolume). This is done by parsing |
| * out the URL parameters and loading them into the relevant EC2XXX object(s). Once |
| * the parameters are loaded the appropriate EC2Engine function is called to perform |
| * the requested action. The result of the EC2Engine function is a standard |
| * Amazon WSDL defined object (e.g., AttachVolumeResponse Java object). Finally the |
| * serialize method is called on the returned response object to obtain the extected |
| * response XML. |
| */ |
| private void attachVolume(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Volume EC2request = new EC2Volume(); |
| |
| // -> all these parameters are required |
| String[] volumeId = request.getParameterValues("VolumeId"); |
| if (null != volumeId && 0 < volumeId.length) |
| EC2request.setId(volumeId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - VolumeId"); |
| } |
| |
| String[] instanceId = request.getParameterValues("InstanceId"); |
| if (null != instanceId && 0 < instanceId.length) |
| EC2request.setInstanceId(instanceId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| String[] device = request.getParameterValues("Device"); |
| if (null != device && 0 < device.length) |
| EC2request.setDevice(device[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Device"); |
| } |
| |
| // -> execute the request |
| AttachVolumeResponse EC2response = EC2SoapServiceImpl.toAttachVolumeResponse(ServiceProvider.getInstance().getEC2Engine().attachVolume(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| /** |
| * The SOAP equivalent of this function appears to allow multiple permissions per request, yet |
| * in the REST API documentation only one permission is allowed. |
| */ |
| private void revokeSecurityGroupIngress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2AuthorizeRevokeSecurityGroup EC2request = new EC2AuthorizeRevokeSecurityGroup(); |
| |
| String[] groupName = request.getParameterValues("GroupName"); |
| if (null != groupName && 0 < groupName.length) |
| EC2request.setName(groupName[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - GroupName"); |
| } |
| |
| // -> not clear how many parameters there are until we fail to get IpPermissions.n.IpProtocol |
| int nCount = 1, mCount; |
| do { |
| EC2IpPermission perm = new EC2IpPermission(); |
| |
| String[] protocol = request.getParameterValues("IpPermissions." + nCount + ".IpProtocol"); |
| if (null != protocol && 0 < protocol.length) |
| perm.setProtocol(protocol[0]); |
| else |
| break; |
| |
| String[] fromPort = request.getParameterValues("IpPermissions." + nCount + ".FromPort"); |
| if (null != fromPort && 0 < fromPort.length) { |
| if (protocol[0].equalsIgnoreCase("icmp")) |
| perm.setIcmpType(fromPort[0]); |
| else |
| perm.setFromPort(Integer.parseInt(fromPort[0])); |
| } |
| |
| String[] toPort = request.getParameterValues("IpPermissions." + nCount + ".ToPort"); |
| if (null != toPort && 0 < toPort.length) { |
| if (protocol[0].equalsIgnoreCase("icmp")) |
| perm.setIcmpCode(toPort[0]); |
| else |
| perm.setToPort(Integer.parseInt(toPort[0])); |
| } |
| |
| // -> list: IpPermissions.n.IpRanges.m.CidrIp |
| mCount = 1; |
| do { |
| String[] ranges = request.getParameterValues("IpPermissions." + nCount + ".IpRanges." + mCount + ".CidrIp"); |
| if (null != ranges && 0 < ranges.length) |
| perm.addIpRange(ranges[0]); |
| else |
| break; |
| mCount++; |
| } while (true); |
| |
| // -> list: IpPermissions.n.Groups.m.UserId and IpPermissions.n.Groups.m.GroupName |
| mCount = 1; |
| do { |
| EC2SecurityGroup group = new EC2SecurityGroup(); |
| |
| String[] user = request.getParameterValues("IpPermissions." + nCount + ".Groups." + mCount + ".UserId"); |
| if (null != user && 0 < user.length) |
| group.setAccount(user[0]); |
| else |
| break; |
| |
| String[] name = request.getParameterValues("IpPermissions." + nCount + ".Groups." + mCount + ".GroupName"); |
| if (null != name && 0 < name.length) |
| group.setName(name[0]); |
| else |
| break; |
| |
| perm.addUser(group); |
| mCount++; |
| } while (true); |
| |
| // -> multiple IP permissions can be specified per group name |
| EC2request.addIpPermission(perm); |
| nCount++; |
| } while (true); |
| |
| if (1 == nCount) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - IpPermissions"); |
| } |
| |
| // -> execute the request |
| RevokeSecurityGroupIngressResponse EC2response = EC2SoapServiceImpl.toRevokeSecurityGroupIngressResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .revokeSecurityGroup(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void authorizeSecurityGroupIngress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| // -> parse the complicated paramters into our standard object |
| EC2AuthorizeRevokeSecurityGroup EC2request = new EC2AuthorizeRevokeSecurityGroup(); |
| |
| String[] groupName = request.getParameterValues("GroupName"); |
| if (null != groupName && 0 < groupName.length) |
| EC2request.setName(groupName[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter 'Groupname'"); |
| } |
| |
| // -> not clear how many parameters there are until we fail to get IpPermissions.n.IpProtocol |
| int nCount = 1; |
| do { |
| EC2IpPermission perm = new EC2IpPermission(); |
| |
| String[] protocol = request.getParameterValues("IpPermissions." + nCount + ".IpProtocol"); |
| if (null != protocol && 0 < protocol.length) |
| perm.setProtocol(protocol[0]); |
| else |
| break; |
| |
| String[] fromPort = request.getParameterValues("IpPermissions." + nCount + ".FromPort"); |
| if (null != fromPort && 0 < fromPort.length) { |
| if (protocol[0].equalsIgnoreCase("icmp")) |
| perm.setIcmpType(fromPort[0]); |
| else |
| perm.setFromPort(Integer.parseInt(fromPort[0])); |
| } |
| |
| String[] toPort = request.getParameterValues("IpPermissions." + nCount + ".ToPort"); |
| if (null != toPort && 0 < toPort.length) { |
| if (protocol[0].equalsIgnoreCase("icmp")) |
| perm.setIcmpCode(toPort[0]); |
| else |
| perm.setToPort(Integer.parseInt(toPort[0])); |
| } |
| |
| // -> list: IpPermissions.n.IpRanges.m.CidrIp |
| int mCount = 1; |
| do { |
| String[] ranges = request.getParameterValues("IpPermissions." + nCount + ".IpRanges." + mCount + ".CidrIp"); |
| if (null != ranges && 0 < ranges.length) |
| perm.addIpRange(ranges[0]); |
| else |
| break; |
| mCount++; |
| |
| } while (true); |
| |
| // -> list: IpPermissions.n.Groups.m.UserId and IpPermissions.n.Groups.m.GroupName |
| mCount = 1; |
| do { |
| String[] user = request.getParameterValues("IpPermissions." + nCount + ".Groups." + mCount + ".UserId"); |
| if (null == user || 0 == user.length) |
| break; |
| |
| String[] name = request.getParameterValues("IpPermissions." + nCount + ".Groups." + mCount + ".GroupName"); |
| if (null == name || 0 == name.length) |
| break; |
| |
| EC2SecurityGroup group = new EC2SecurityGroup(); |
| group.setAccount(user[0]); |
| group.setName(name[0]); |
| perm.addUser(group); |
| mCount++; |
| |
| } while (true); |
| |
| // -> multiple IP permissions can be specified per group name |
| EC2request.addIpPermission(perm); |
| nCount++; |
| |
| } while (true); |
| |
| if (1 == nCount) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - IpPermissions"); |
| } |
| |
| // -> execute the request |
| AuthorizeSecurityGroupIngressResponse EC2response = EC2SoapServiceImpl.toAuthorizeSecurityGroupIngressResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .authorizeSecurityGroup(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void detachVolume(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Volume EC2request = new EC2Volume(); |
| |
| String[] volumeId = request.getParameterValues("VolumeId"); |
| if (null != volumeId && 0 < volumeId.length) |
| EC2request.setId(volumeId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter 'VolumeId'"); |
| } |
| |
| String[] instanceId = request.getParameterValues("InstanceId"); |
| if (null != instanceId && 0 < instanceId.length) |
| EC2request.setInstanceId(instanceId[0]); |
| |
| String[] device = request.getParameterValues("Device"); |
| if (null != device && 0 < device.length) |
| EC2request.setDevice(device[0]); |
| |
| // -> execute the request |
| DetachVolumeResponse EC2response = EC2SoapServiceImpl.toDetachVolumeResponse(ServiceProvider.getInstance().getEC2Engine().detachVolume(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void deleteVolume(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Volume EC2request = new EC2Volume(); |
| |
| String[] volumeId = request.getParameterValues("VolumeId"); |
| if (null != volumeId && 0 < volumeId.length) |
| EC2request.setId(volumeId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - VolumeId"); |
| } |
| |
| // -> execute the request |
| DeleteVolumeResponse EC2response = EC2SoapServiceImpl.toDeleteVolumeResponse(ServiceProvider.getInstance().getEC2Engine().deleteVolume(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void createVolume(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2CreateVolume EC2request = new EC2CreateVolume(); |
| |
| String[] zoneName = request.getParameterValues("AvailabilityZone"); |
| if (null != zoneName && 0 < zoneName.length) |
| EC2request.setZoneName(zoneName[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing parameter - AvailabilityZone"); |
| } |
| |
| String[] size = request.getParameterValues("Size"); |
| String[] snapshotId = request.getParameterValues("SnapshotId"); |
| boolean useSnapshot = false; |
| boolean useSize = false; |
| |
| if (null != size && 0 < size.length) |
| useSize = true; |
| |
| if (snapshotId != null && snapshotId.length != 0) |
| useSnapshot = true; |
| |
| if (useSize && !useSnapshot) { |
| EC2request.setSize(size[0]); |
| } else if (useSnapshot && !useSize) { |
| EC2request.setSnapshotId(snapshotId[0]); |
| } else if (useSize && useSnapshot) { |
| throw new EC2ServiceException(ClientError.InvalidParameterCombination, "Parameters 'Size' and 'SnapshotId' are mutually exclusive"); |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Parameter 'Size' or 'SnapshotId' has to be specified"); |
| } |
| |
| // -> execute the request |
| CreateVolumeResponse EC2response = EC2SoapServiceImpl.toCreateVolumeResponse(ServiceProvider.getInstance().getEC2Engine().createVolume(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void createSecurityGroup(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| |
| String groupName, groupDescription = null; |
| |
| String[] name = request.getParameterValues("GroupName"); |
| if (null != name && 0 < name.length) |
| groupName = name[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - GroupName"); |
| } |
| String[] desc = request.getParameterValues("GroupDescription"); |
| if (null != desc && 0 < desc.length) |
| groupDescription = desc[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - GroupDescription"); |
| } |
| |
| // -> execute the request |
| CreateSecurityGroupResponse EC2response = EC2SoapServiceImpl.toCreateSecurityGroupResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .createSecurityGroup(groupName, groupDescription)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void deleteSecurityGroup(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String groupName = null; |
| |
| String[] name = request.getParameterValues("GroupName"); |
| if (null != name && 0 < name.length) |
| groupName = name[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - GroupName"); |
| } |
| |
| // -> execute the request |
| DeleteSecurityGroupResponse EC2response = EC2SoapServiceImpl.toDeleteSecurityGroupResponse(ServiceProvider.getInstance().getEC2Engine().deleteSecurityGroup(groupName)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void deleteSnapshot(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String snapshotId = null; |
| |
| String[] snapSet = request.getParameterValues("SnapshotId"); |
| if (null != snapSet && 0 < snapSet.length) |
| snapshotId = snapSet[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - SnapshotId"); |
| } |
| |
| // -> execute the request |
| DeleteSnapshotResponse EC2response = EC2SoapServiceImpl.toDeleteSnapshotResponse(ServiceProvider.getInstance().getEC2Engine().deleteSnapshot(snapshotId)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void createSnapshot(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String volumeId = null; |
| |
| String[] volSet = request.getParameterValues("VolumeId"); |
| if (null != volSet && 0 < volSet.length) |
| volumeId = volSet[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - VolumeId"); |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| CreateSnapshotResponse EC2response = EC2SoapServiceImpl.toCreateSnapshotResponse(engine.createSnapshot(volumeId), engine); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void deregisterImage(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Image image = new EC2Image(); |
| |
| String[] imageId = request.getParameterValues("ImageId"); |
| if (null != imageId && 0 < imageId.length) |
| image.setId(imageId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ImageId"); |
| } |
| |
| // -> execute the request |
| DeregisterImageResponse EC2response = EC2SoapServiceImpl.toDeregisterImageResponse(ServiceProvider.getInstance().getEC2Engine().deregisterImage(image)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void createImage(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2CreateImage EC2request = new EC2CreateImage(); |
| |
| String[] instanceId = request.getParameterValues("InstanceId"); |
| if (null != instanceId && 0 < instanceId.length) |
| EC2request.setInstanceId(instanceId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| String[] name = request.getParameterValues("Name"); |
| if (null != name && 0 < name.length) |
| EC2request.setName(name[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Name"); |
| } |
| |
| String[] description = request.getParameterValues("Description"); |
| if (null != description && 0 < description.length) { |
| if (description[0].length() > 255) |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Length of the value of parameter Description should be less than 255"); |
| EC2request.setDescription(description[0]); |
| } |
| |
| // -> execute the request |
| CreateImageResponse EC2response = EC2SoapServiceImpl.toCreateImageResponse(ServiceProvider.getInstance().getEC2Engine().createImage(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void registerImage(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2RegisterImage EC2request = new EC2RegisterImage(); |
| |
| String[] location = request.getParameterValues("ImageLocation"); |
| if (null != location && 0 < location.length) |
| EC2request.setLocation(location[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing parameter - ImageLocation"); |
| } |
| |
| String[] cloudRedfined = request.getParameterValues("Architecture"); |
| if (null != cloudRedfined && 0 < cloudRedfined.length) |
| EC2request.setArchitecture(cloudRedfined[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Architecture"); |
| } |
| |
| String[] name = request.getParameterValues("Name"); |
| if (null != name && 0 < name.length) |
| EC2request.setName(name[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Name"); |
| } |
| |
| String[] description = request.getParameterValues("Description"); |
| if (null != description && 0 < description.length) |
| EC2request.setDescription(description[0]); |
| |
| // -> execute the request |
| RegisterImageResponse EC2response = EC2SoapServiceImpl.toRegisterImageResponse(ServiceProvider.getInstance().getEC2Engine().registerImage(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void modifyImageAttribute(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); |
| |
| String[] imageId = request.getParameterValues("ImageId"); |
| if (imageId != null && imageId.length > 0) |
| ec2request.setImageId(imageId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ImageId"); |
| } |
| |
| String[] description = request.getParameterValues("Description.Value"); |
| if (description != null && description.length > 0) { |
| ec2request.setAttribute(ImageAttribute.description); |
| ec2request.setDescription(description[0]); |
| } else { |
| //add all launch permissions to ec2request |
| ec2request = addLaunchPermImageAttribute(request, ec2request); |
| if (ec2request.getLaunchPermissionSet().length > 0) |
| ec2request.setAttribute(ImageAttribute.launchPermission); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Description/LaunchPermission should be provided"); |
| } |
| } |
| |
| // -> execute the request |
| ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private EC2ModifyImageAttribute addLaunchPermImageAttribute(HttpServletRequest request, EC2ModifyImageAttribute ec2request) { |
| String[] users = {".UserId", ".Group"}; |
| String[] operations = {"LaunchPermission.Add.", "LaunchPermission.Remove."}; |
| int nCount = 1; |
| |
| for (int i = 0; i < 2; i++) { |
| for (int j = 0; j < 2; j++) { |
| List<String> launchPermissionList = new ArrayList<String>(); |
| do { |
| String[] launchPermissionAddGroup = request.getParameterValues(operations[j] + nCount + users[i]); |
| if (launchPermissionAddGroup != null && launchPermissionAddGroup.length > 0) |
| launchPermissionList.add(launchPermissionAddGroup[0]); |
| else |
| break; |
| nCount++; |
| } while (true); |
| if (nCount != 1) { |
| EC2ImageLaunchPermission ec2LaunchPermission = new EC2ImageLaunchPermission(); |
| if (operations[j].contains("Add")) |
| ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add); |
| else |
| ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove); |
| for (String launchPerm : launchPermissionList) { |
| ec2LaunchPermission.addLaunchPermission(launchPerm); |
| } |
| ec2request.addLaunchPermission(ec2LaunchPermission); |
| nCount = 1; |
| } |
| } |
| } |
| |
| return ec2request; |
| } |
| |
| private void resetImageAttribute(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); |
| |
| String[] imageId = request.getParameterValues("ImageId"); |
| if (imageId != null && imageId.length > 0) |
| ec2request.setImageId(imageId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ImageId"); |
| } |
| |
| String[] attribute = request.getParameterValues("Attribute"); |
| if (attribute != null && attribute.length > 0) { |
| if (attribute[0].equalsIgnoreCase("launchPermission")) |
| ec2request.setAttribute(ImageAttribute.launchPermission); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Description/LaunchPermission should be provided"); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Attribute"); |
| } |
| |
| EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); |
| launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset); |
| ec2request.addLaunchPermission(launchPermission); |
| |
| // -> execute the request |
| ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse(ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute(ec2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void runInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2RunInstances EC2request = new EC2RunInstances(); |
| |
| // -> so in the Amazon docs for this REST call there is no userData even though there is in the SOAP docs |
| String[] imageId = request.getParameterValues("ImageId"); |
| if (null != imageId && 0 < imageId.length) |
| EC2request.setTemplateId(imageId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ImageId"); |
| } |
| |
| String[] minCount = request.getParameterValues("MinCount"); |
| if (minCount == null || minCount.length < 1) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - MinCount"); |
| } else if (Integer.parseInt(minCount[0]) < 1) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Value of parameter MinCount should be greater than 0"); |
| } else { |
| EC2request.setMinCount(Integer.parseInt(minCount[0])); |
| } |
| |
| String[] maxCount = request.getParameterValues("MaxCount"); |
| if (maxCount == null || maxCount.length < 1) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - MaxCount"); |
| } else if (Integer.parseInt(maxCount[0]) < 1) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Value of parameter MaxCount should be greater than 0"); |
| } else { |
| EC2request.setMaxCount(Integer.parseInt(maxCount[0])); |
| } |
| |
| String[] instanceType = request.getParameterValues("InstanceType"); |
| if (null != instanceType && 0 < instanceType.length) |
| EC2request.setInstanceType(instanceType[0]); |
| |
| String[] zoneName = request.getParameterValues("Placement.AvailabilityZone"); |
| if (null != zoneName && 0 < zoneName.length) |
| EC2request.setZoneName(zoneName[0]); |
| |
| String[] size = request.getParameterValues("size"); |
| if (size != null) { |
| EC2request.setSize(Integer.valueOf(size[0])); |
| } |
| |
| String[] keyName = request.getParameterValues("KeyName"); |
| if (keyName != null) { |
| EC2request.setKeyName(keyName[0]); |
| } |
| |
| String[] userData = request.getParameterValues("UserData"); |
| if (userData != null) { |
| EC2request.setUserData(userData[0]); |
| } |
| |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("SecurityGroup")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) { |
| if (key.startsWith("SecurityGroupId")) |
| EC2request.addSecuritGroupId(value[0]); |
| else |
| EC2request.addSecuritGroupName(value[0]); |
| } |
| } |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| RunInstancesResponse EC2response = EC2SoapServiceImpl.toRunInstancesResponse(engine.runInstances(EC2request), engine); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void rebootInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2RebootInstances EC2request = new EC2RebootInstances(); |
| int count = 0; |
| |
| // -> load in all the "InstanceId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("InstanceId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) { |
| EC2request.addInstanceId(value[0]); |
| count++; |
| } |
| } |
| } |
| if (0 == count) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| // -> execute the request |
| RebootInstancesResponse EC2response = EC2SoapServiceImpl.toRebootInstancesResponse(ServiceProvider.getInstance().getEC2Engine().rebootInstances(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void startInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2StartInstances EC2request = new EC2StartInstances(); |
| int count = 0; |
| |
| // -> load in all the "InstanceId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("InstanceId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) { |
| EC2request.addInstanceId(value[0]); |
| count++; |
| } |
| } |
| } |
| if (0 == count) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| // -> execute the request |
| StartInstancesResponse EC2response = EC2SoapServiceImpl.toStartInstancesResponse(ServiceProvider.getInstance().getEC2Engine().startInstances(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void stopInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2StopInstances EC2request = new EC2StopInstances(); |
| int count = 0; |
| |
| // -> load in all the "InstanceId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("InstanceId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) { |
| EC2request.addInstanceId(value[0]); |
| count++; |
| } |
| } |
| } |
| if (0 == count) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| String[] force = request.getParameterValues("Force"); |
| if (force != null) { |
| EC2request.setForce(Boolean.parseBoolean(force[0])); |
| } |
| |
| // -> execute the request |
| StopInstancesResponse EC2response = EC2SoapServiceImpl.toStopInstancesResponse(ServiceProvider.getInstance().getEC2Engine().stopInstances(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void terminateInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2StopInstances EC2request = new EC2StopInstances(); |
| int count = 0; |
| |
| // -> load in all the "InstanceId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("InstanceId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) { |
| EC2request.addInstanceId(value[0]); |
| count++; |
| } |
| } |
| } |
| if (0 == count) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| // -> execute the request |
| EC2request.setDestroyInstances(true); |
| TerminateInstancesResponse EC2response = EC2SoapServiceImpl.toTermInstancesResponse(ServiceProvider.getInstance().getEC2Engine().stopInstances(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| /** |
| * We are reusing the SOAP code to process this request. We then use Axiom to serialize the |
| * resulting EC2 Amazon object into XML to return to the client. |
| */ |
| private void describeAvailabilityZones(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeAvailabilityZones EC2request = new EC2DescribeAvailabilityZones(); |
| |
| // -> load in all the "ZoneName.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("ZoneName")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addZone(value[0]); |
| } |
| } |
| |
| // add filters |
| EC2Filter[] filterSet = extractFilters(request); |
| if (filterSet != null) { |
| EC2AvailabilityZonesFilterSet afs = new EC2AvailabilityZonesFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) { |
| afs.addFilter(filterSet[i]); |
| } |
| EC2request.setFilterSet(afs); |
| } |
| |
| // -> execute the request |
| DescribeAvailabilityZonesResponse EC2response = EC2SoapServiceImpl.toDescribeAvailabilityZonesResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .describeAvailabilityZones(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeImages(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeImages EC2request = new EC2DescribeImages(); |
| |
| // -> load in all the "ImageId.n" parameters if any, and ignore all other parameters |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("ImageId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addImageSet(value[0]); |
| } |
| } |
| // add filters |
| EC2Filter[] filterSet = extractFilters(request); |
| if (filterSet != null) { |
| EC2ImageFilterSet ifs = new EC2ImageFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) { |
| ifs.addFilter(filterSet[i]); |
| } |
| EC2request.setFilterSet(ifs); |
| } |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| DescribeImagesResponse EC2response = EC2SoapServiceImpl.toDescribeImagesResponse(engine.describeImages(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeImageAttribute(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeImageAttribute ec2request = new EC2DescribeImageAttribute(); |
| |
| String[] imageId = request.getParameterValues("ImageId"); |
| if (imageId != null && imageId.length > 0) |
| ec2request.setImageId(imageId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ImageId"); |
| } |
| |
| String[] attribute = request.getParameterValues("Attribute"); |
| if (attribute != null && attribute.length > 0) { |
| if (attribute[0].equalsIgnoreCase("description")) |
| ec2request.setAttribute(ImageAttribute.description); |
| else if (attribute[0].equalsIgnoreCase("launchPermission")) |
| ec2request.setAttribute(ImageAttribute.launchPermission); |
| else { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Only values supported for paramter Attribute are - Description/LaunchPermission"); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Attribute"); |
| } |
| |
| DescribeImageAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeImageAttributeResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .describeImageAttribute(ec2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeInstances(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeInstances EC2request = new EC2DescribeInstances(); |
| |
| // -> load in all the "InstanceId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("InstanceId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addInstanceId(value[0]); |
| } |
| } |
| |
| // -> are there any filters with this request? |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2InstanceFilterSet ifs = new EC2InstanceFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) |
| ifs.addFilter(filterSet[i]); |
| EC2request.setFilterSet(ifs); |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| DescribeInstancesResponse EC2response = EC2SoapServiceImpl.toDescribeInstancesResponse(engine.describeInstances(EC2request), engine); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeAddresses(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeAddresses ec2Request = new EC2DescribeAddresses(); |
| |
| // -> load in all the "PublicIp.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("PublicIp")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| ec2Request.addPublicIp(value[0]); |
| } |
| } |
| |
| // add filters |
| EC2Filter[] filterSet = extractFilters(request); |
| if (filterSet != null) { |
| EC2AddressFilterSet afs = new EC2AddressFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) |
| afs.addFilter(filterSet[i]); |
| ec2Request.setFilterSet(afs); |
| } |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| serializeResponse(response, EC2SoapServiceImpl.toDescribeAddressesResponse(engine.describeAddresses(ec2Request))); |
| } |
| |
| private void allocateAddress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| |
| AllocateAddressResponse ec2Response = EC2SoapServiceImpl.toAllocateAddressResponse(engine.allocateAddress()); |
| |
| serializeResponse(response, ec2Response); |
| } |
| |
| private void releaseAddress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| |
| String publicIp = request.getParameter("PublicIp"); |
| if (publicIp == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - PublicIp"); |
| } |
| |
| EC2ReleaseAddress ec2Request = new EC2ReleaseAddress(); |
| if (ec2Request != null) { |
| ec2Request.setPublicIp(publicIp); |
| } |
| |
| ReleaseAddressResponse EC2Response = EC2SoapServiceImpl.toReleaseAddressResponse(engine.releaseAddress(ec2Request)); |
| |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void associateAddress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| |
| String publicIp = request.getParameter("PublicIp"); |
| if (null == publicIp) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - PublicIp"); |
| } |
| String instanceId = request.getParameter("InstanceId"); |
| if (null == instanceId) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| EC2AssociateAddress ec2Request = new EC2AssociateAddress(); |
| if (ec2Request != null) { |
| ec2Request.setInstanceId(instanceId); |
| ec2Request.setPublicIp(publicIp); |
| } |
| |
| AssociateAddressResponse ec2Response = EC2SoapServiceImpl.toAssociateAddressResponse(engine.associateAddress(ec2Request)); |
| |
| serializeResponse(response, ec2Response); |
| } |
| |
| private void disassociateAddress(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| |
| String publicIp = request.getParameter("PublicIp"); |
| if (null == publicIp) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - PublicIp"); |
| } |
| |
| EC2DisassociateAddress ec2Request = new EC2DisassociateAddress(); |
| if (ec2Request != null) { |
| ec2Request.setPublicIp(publicIp); |
| } |
| |
| DisassociateAddressResponse ec2Response = EC2SoapServiceImpl.toDisassociateAddressResponse(engine.disassociateAddress(ec2Request)); |
| |
| serializeResponse(response, ec2Response); |
| } |
| |
| private void describeSecurityGroups(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeSecurityGroups EC2request = new EC2DescribeSecurityGroups(); |
| |
| // -> load in all the "GroupName.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("GroupName")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addGroupName(value[0]); |
| } |
| } |
| |
| // -> are there any filters with this request? |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2GroupFilterSet gfs = new EC2GroupFilterSet(); |
| for (EC2Filter filter : filterSet) |
| gfs.addFilter(filter); |
| EC2request.setFilterSet(gfs); |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| |
| DescribeSecurityGroupsResponse EC2response = EC2SoapServiceImpl.toDescribeSecurityGroupsResponse(engine.describeSecurityGroups(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeInstanceAttribute(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeInstances EC2request = new EC2DescribeInstances(); |
| String[] instanceId = request.getParameterValues("InstanceId"); |
| if (instanceId != null && instanceId.length > 0) |
| EC2request.addInstanceId(instanceId[0]); |
| else |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| |
| String[] attribute = request.getParameterValues("Attribute"); |
| if (attribute != null && attribute.length > 0) { |
| if (!attribute[0].equalsIgnoreCase("instanceType")) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Only value supported for paramter Attribute is 'instanceType'"); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Attribute"); |
| } |
| |
| // -> execute the request |
| DescribeInstanceAttributeResponse EC2response = EC2SoapServiceImpl.toDescribeInstanceAttributeResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .describeInstances(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void modifyInstanceAttribute(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2ModifyInstanceAttribute ec2Request = new EC2ModifyInstanceAttribute(); |
| |
| String[] instanceId = request.getParameterValues("InstanceId"); |
| if (instanceId != null && instanceId.length > 0) |
| ec2Request.setInstanceId(instanceId[0]); |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| String[] instanceType = request.getParameterValues("InstanceType.Value"); |
| String[] userData = request.getParameterValues("UserData.Value"); |
| |
| if (instanceType != null && userData != null) { |
| throw new EC2ServiceException(ClientError.InvalidParameterCombination, "Only one attribute can be" + " specified at a time"); |
| } |
| if (instanceType != null && instanceType.length > 0) { |
| ec2Request.setInstanceType(instanceType[0]); |
| } else if (userData != null && userData.length > 0) { |
| ec2Request.setUserData(userData[0]); |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing parameter - InstanceType/UserData should be provided"); |
| } |
| |
| // -> execute the request |
| ModifyInstanceAttributeResponse EC2response = EC2SoapServiceImpl.toModifyInstanceAttributeResponse(ServiceProvider.getInstance() |
| .getEC2Engine() |
| .modifyInstanceAttribute(ec2Request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeSnapshots(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeSnapshots EC2request = new EC2DescribeSnapshots(); |
| |
| // -> load in all the "SnapshotId.n" parameters if any, and ignore any other parameters |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("SnapshotId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addSnapshotId(value[0]); |
| } |
| } |
| |
| // -> are there any filters with this request? |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2SnapshotFilterSet sfs = new EC2SnapshotFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) |
| sfs.addFilter(filterSet[i]); |
| EC2request.setFilterSet(sfs); |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| DescribeSnapshotsResponse EC2response = EC2SoapServiceImpl.toDescribeSnapshotsResponse(engine.describeSnapshots(EC2request)); |
| serializeResponse(response, EC2response); |
| } |
| |
| private void describeVolumes(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeVolumes EC2request = new EC2DescribeVolumes(); |
| |
| // -> load in all the "VolumeId.n" parameters if any |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("VolumeId")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| EC2request.addVolumeId(value[0]); |
| } |
| } |
| |
| // -> are there any filters with this request? |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2VolumeFilterSet vfs = new EC2VolumeFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) |
| vfs.addFilter(filterSet[i]); |
| EC2request.setFilterSet(vfs); |
| } |
| |
| // -> execute the request |
| EC2Engine engine = ServiceProvider.getInstance().getEC2Engine(); |
| DescribeVolumesResponse EC2response = EC2SoapServiceImpl.toDescribeVolumesResponse(ServiceProvider.getInstance().getEC2Engine().describeVolumes(EC2request), engine); |
| serializeResponse(response, EC2response); |
| } |
| |
| /** |
| * Example of how the filters are defined in a REST request: |
| * https://<server>/?Action=DescribeVolumes |
| * &Filter.1.Name=attachment.instance-id |
| * &Filter.1.Value.1=i-1a2b3c4d |
| * &Filter.2.Name=attachment.delete-on-termination |
| * &Filter.2.Value.1=true |
| * |
| * @param request |
| * @return List<EC2Filter> |
| */ |
| private EC2Filter[] extractFilters(HttpServletRequest request) { |
| String filterName = null; |
| String value = null; |
| EC2Filter nextFilter = null; |
| boolean timeFilter = false; |
| int filterCount = 1; |
| int valueCount = 1; |
| |
| List<EC2Filter> filterSet = new ArrayList<EC2Filter>(); |
| |
| do { |
| filterName = request.getParameter("Filter." + filterCount + ".Name"); |
| if (null != filterName) { |
| nextFilter = new EC2Filter(); |
| nextFilter.setName(filterName); |
| timeFilter = (filterName.equalsIgnoreCase("attachment.attach-time") || filterName.equalsIgnoreCase("create-time")); |
| valueCount = 1; |
| do { |
| value = request.getParameter("Filter." + filterCount + ".Value." + valueCount); |
| if (null != value) { |
| // -> time values are not encoded as regexes |
| if (timeFilter) |
| nextFilter.addValue(value); |
| else |
| nextFilter.addValueEncoded(value); |
| |
| valueCount++; |
| } |
| } while (null != value); |
| |
| filterSet.add(nextFilter); |
| filterCount++; |
| } |
| } while (null != filterName); |
| |
| if (1 == filterCount) |
| return null; |
| else |
| return filterSet.toArray(new EC2Filter[0]); |
| } |
| |
| private void describeKeyPairs(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeKeyPairs ec2Request = new EC2DescribeKeyPairs(); |
| |
| Enumeration<?> names = request.getParameterNames(); |
| while (names.hasMoreElements()) { |
| String key = (String)names.nextElement(); |
| if (key.startsWith("KeyName")) { |
| String[] value = request.getParameterValues(key); |
| if (null != value && 0 < value.length) |
| ec2Request.addKeyName(value[0]); |
| } |
| } |
| |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2KeyPairFilterSet vfs = new EC2KeyPairFilterSet(); |
| for (EC2Filter filter : filterSet) { |
| vfs.addFilter(filter); |
| } |
| ec2Request.setKeyFilterSet(vfs); |
| } |
| |
| DescribeKeyPairsResponse EC2Response = EC2SoapServiceImpl.toDescribeKeyPairs(ServiceProvider.getInstance().getEC2Engine().describeKeyPairs(ec2Request)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void importKeyPair(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| |
| String keyName = request.getParameter("KeyName"); |
| if (keyName == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - KeyName"); |
| } |
| |
| String publicKeyMaterial = request.getParameter("PublicKeyMaterial"); |
| if (publicKeyMaterial == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - PublicKeyMaterial"); |
| } |
| |
| if (!publicKeyMaterial.contains(" ")) |
| publicKeyMaterial = new String(Base64.decodeBase64(publicKeyMaterial.getBytes())); |
| |
| EC2ImportKeyPair ec2Request = new EC2ImportKeyPair(); |
| if (ec2Request != null) { |
| ec2Request.setKeyName(request.getParameter("KeyName")); |
| ec2Request.setPublicKeyMaterial(request.getParameter("PublicKeyMaterial")); |
| } |
| |
| ImportKeyPairResponse EC2Response = EC2SoapServiceImpl.toImportKeyPair(ServiceProvider.getInstance().getEC2Engine().importKeyPair(ec2Request)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void createKeyPair(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String keyName = request.getParameter("KeyName"); |
| if (keyName == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - KeyName"); |
| } |
| |
| EC2CreateKeyPair ec2Request = new EC2CreateKeyPair(); |
| if (ec2Request != null) { |
| ec2Request.setKeyName(keyName); |
| } |
| |
| CreateKeyPairResponse EC2Response = EC2SoapServiceImpl.toCreateKeyPair(ServiceProvider.getInstance().getEC2Engine().createKeyPair(ec2Request)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void deleteKeyPair(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String keyName = request.getParameter("KeyName"); |
| if (keyName == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - KeyName"); |
| } |
| |
| EC2DeleteKeyPair ec2Request = new EC2DeleteKeyPair(); |
| ec2Request.setKeyName(keyName); |
| |
| DeleteKeyPairResponse EC2Response = EC2SoapServiceImpl.toDeleteKeyPair(ServiceProvider.getInstance().getEC2Engine().deleteKeyPair(ec2Request)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void getPasswordData(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| String instanceId = request.getParameter("InstanceId"); |
| if (instanceId == null) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - InstanceId"); |
| } |
| |
| GetPasswordDataResponse EC2Response = EC2SoapServiceImpl.toGetPasswordData(ServiceProvider.getInstance().getEC2Engine().getPasswordData(instanceId)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void createTags(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Tags ec2Request = createTagsRequest(request, response); |
| if (ec2Request == null) |
| return; |
| CreateTagsResponse EC2Response = EC2SoapServiceImpl.toCreateTagsResponse(ServiceProvider.getInstance().getEC2Engine().modifyTags(ec2Request, "create")); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private void deleteTags(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2Tags ec2Request = createTagsRequest(request, response); |
| if (ec2Request == null) |
| return; |
| DeleteTagsResponse EC2Response = EC2SoapServiceImpl.toDeleteTagsResponse(ServiceProvider.getInstance().getEC2Engine().modifyTags(ec2Request, "delete")); |
| serializeResponse(response, EC2Response); |
| } |
| |
| private EC2Tags createTagsRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { |
| EC2Tags ec2Request = new EC2Tags(); |
| ArrayList<String> resourceIdList = new ArrayList<String>(); |
| Map<String, String> resourceTagList = new HashMap<String, String>(); |
| |
| int nCount = 1; |
| do { |
| String[] resourceIds = request.getParameterValues("ResourceId." + nCount); |
| if (resourceIds != null && resourceIds.length > 0) |
| resourceIdList.add(resourceIds[0]); |
| else |
| break; |
| nCount++; |
| } while (true); |
| if (resourceIdList.isEmpty()) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ResourceId"); |
| } |
| ec2Request = EC2SoapServiceImpl.toResourceTypeAndIds(ec2Request, resourceIdList); |
| |
| nCount = 1; |
| do { |
| String[] tagKey = request.getParameterValues("Tag." + nCount + ".Key"); |
| if (tagKey != null && tagKey.length > 0) { |
| String[] tagValue = request.getParameterValues("Tag." + nCount + ".Value"); |
| if (tagValue != null && tagValue.length > 0) { |
| resourceTagList.put(tagKey[0], tagValue[0]); |
| } else |
| resourceTagList.put(tagKey[0], null); |
| } else |
| break; |
| nCount++; |
| } while (true); |
| if (resourceTagList.isEmpty()) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - ResourceTag"); |
| } |
| ec2Request = EC2SoapServiceImpl.toResourceTag(ec2Request, resourceTagList); |
| |
| return ec2Request; |
| } |
| |
| private void describeTags(HttpServletRequest request, HttpServletResponse response) throws ADBException, XMLStreamException, IOException { |
| EC2DescribeTags ec2Request = new EC2DescribeTags(); |
| |
| EC2Filter[] filterSet = extractFilters(request); |
| if (null != filterSet) { |
| EC2TagsFilterSet tfs = new EC2TagsFilterSet(); |
| for (int i = 0; i < filterSet.length; i++) |
| tfs.addFilter(filterSet[i]); |
| ec2Request.setFilterSet(tfs); |
| } |
| DescribeTagsResponse EC2Response = EC2SoapServiceImpl.toDescribeTagsResponse(ServiceProvider.getInstance().getEC2Engine().describeTags(ec2Request)); |
| serializeResponse(response, EC2Response); |
| } |
| |
| /** |
| * This function implements the EC2 REST authentication algorithm. It uses the given |
| * "AWSAccessKeyId" parameter to look up the Cloud.com account holder's secret key which is |
| * used as input to the signature calculation. In addition, it tests the given "Expires" |
| * parameter to see if the signature has expired and if so the request fails. |
| */ |
| private boolean authenticateRequest(HttpServletRequest request, HttpServletResponse response) throws SignatureException, IOException, InstantiationException, |
| IllegalAccessException, ClassNotFoundException, SQLException, ParseException { |
| String cloudSecretKey = null; |
| String cloudAccessKey = null; |
| String signature = null; |
| String sigMethod = null; |
| |
| // [A] Basic parameters required for an authenticated rest request |
| // -> note that the Servlet engine will un-URL encode all parameters we extract via "getParameterValues()" calls |
| String[] awsAccess = request.getParameterValues("AWSAccessKeyId"); |
| if (null != awsAccess && 0 < awsAccess.length) |
| cloudAccessKey = awsAccess[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - AWSAccessKeyId"); |
| } |
| |
| String[] clientSig = request.getParameterValues("Signature"); |
| if (null != clientSig && 0 < clientSig.length) |
| signature = clientSig[0]; |
| else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Signature"); |
| } |
| |
| String[] method = request.getParameterValues("SignatureMethod"); |
| if (null != method && 0 < method.length) { |
| sigMethod = method[0]; |
| if (!sigMethod.equals("HmacSHA256") && !sigMethod.equals("HmacSHA1")) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Unsupported SignatureMethod value: " + sigMethod + " expecting: HmacSHA256 or HmacSHA1"); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - SignatureMethod"); |
| } |
| |
| String[] version = request.getParameterValues("Version"); |
| if (null != version && 0 < version.length) { |
| if (!version[0].equals(wsdlVersion)) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Unsupported Version value: " + version[0] + " expecting: " + wsdlVersion); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - Version"); |
| } |
| |
| String[] sigVersion = request.getParameterValues("SignatureVersion"); |
| if (null != sigVersion && 0 < sigVersion.length) { |
| if (!sigVersion[0].equals("2")) { |
| throw new EC2ServiceException(ClientError.InvalidParameterValue, "Unsupported SignatureVersion value: " + sigVersion[0] + " expecting: 2"); |
| } |
| } else { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter - SignatureVersion"); |
| } |
| |
| // -> can have only one but not both { Expires | Timestamp } headers |
| String[] expires = request.getParameterValues("Expires"); |
| if (null != expires && 0 < expires.length) { |
| // -> contains the date and time at which the signature included in the request EXPIRES |
| if (hasSignatureExpired(expires[0])) { //InvalidSecurity.RequestHasExpired |
| throw new EC2ServiceException(ClientError.InvalidSecurity_RequestHasExpired, "Expires parameter indicates signature has expired: " + expires[0]); |
| } |
| } else { // -> contains the date and time at which the request is SIGNED |
| String[] time = request.getParameterValues("Timestamp"); |
| if (null == time || 0 == time.length) { |
| throw new EC2ServiceException(ClientError.MissingParamter, "Missing required parameter -" + " Timestamp/Expires"); |
| } |
| } |
| |
| // [B] Use the access key to get the users secret key from the cloud DB |
| cloudSecretKey = userDao.getSecretKeyByAccessKey(cloudAccessKey); |
| if (cloudSecretKey == null) { |
| logger.debug("Access key '" + cloudAccessKey + "' not found in the the EC2 service "); |
| throw new EC2ServiceException(ClientError.AuthFailure, "Access key '" + cloudAccessKey + "' not found in the the EC2 service "); |
| } |
| |
| // [C] Verify the signature |
| // -> getting the query-string in this way maintains its URL encoding |
| EC2RestAuth restAuth = new EC2RestAuth(); |
| restAuth.setHostHeader(request.getHeader("Host")); |
| String requestUri = request.getRequestURI(); |
| |
| // If forwarded from another basepath: |
| String forwardedPath = (String)request.getAttribute("javax.servlet.forward.request_uri"); |
| if (forwardedPath != null) { |
| requestUri = forwardedPath; |
| } |
| restAuth.setHTTPRequestURI(requestUri); |
| |
| String queryString = request.getQueryString(); |
| // getQueryString returns null (does it ever NOT return null for these), |
| // we need to construct queryString to avoid changing the auth code... |
| if (queryString == null) { |
| // construct our idea of a queryString with parameters! |
| Enumeration<?> params = request.getParameterNames(); |
| if (params != null) { |
| while (params.hasMoreElements()) { |
| String paramName = (String)params.nextElement(); |
| // exclude the signature string obviously. ;) |
| if (paramName.equalsIgnoreCase("Signature")) |
| continue; |
| // URLEncoder performs application/x-www-form-urlencoded-type encoding and not Percent encoding |
| // according to RFC 3986 as required by Amazon, we need to Percent-encode (URL Encode) |
| String encodedValue = URLEncoder.encode(request.getParameter(paramName), "UTF-8").replace("+", "%20").replace("*", "%2A"); |
| if (queryString == null) |
| queryString = paramName + "=" + encodedValue; |
| else |
| queryString = queryString + "&" + paramName + "=" + encodedValue; |
| } |
| } |
| } |
| restAuth.setQueryString(queryString); |
| |
| if (restAuth.verifySignature(request.getMethod(), cloudSecretKey, signature, sigMethod)) { |
| UserContext.current().initContext(cloudAccessKey, cloudSecretKey, cloudAccessKey, "REST request", null); |
| return true; |
| } else |
| throw new EC2ServiceException(ClientError.SignatureDoesNotMatch, "The request signature calculated does not match the signature provided by the user."); |
| } |
| |
| /** |
| * We check this to reduce replay attacks. |
| * |
| * @param timeStamp |
| * @return true - if the request is not longer valid, false otherwise |
| * @throws ParseException |
| */ |
| private boolean hasSignatureExpired(String timeStamp) { |
| Calendar cal = EC2RestAuth.parseDateString(timeStamp); |
| if (null == cal) |
| return false; |
| |
| Date expiredTime = cal.getTime(); |
| Date today = new Date(); // -> gets set to time of creation |
| if (0 >= expiredTime.compareTo(today)) { |
| logger.debug("timestamp given: [" + timeStamp + "], now: [" + today.toString() + "]"); |
| return true; |
| } else |
| return false; |
| } |
| |
| private static void endResponse(HttpServletResponse response, String content) { |
| try { |
| byte[] data = content.getBytes(); |
| response.setContentLength(data.length); |
| OutputStream os = response.getOutputStream(); |
| os.write(data); |
| os.close(); |
| |
| } catch (Throwable e) { |
| logger.error("Unexpected exception " + e.getMessage(), e); |
| } |
| } |
| |
| private void logRequest(HttpServletRequest request) { |
| if (logger.isInfoEnabled()) { |
| logger.info("EC2 Request method: " + request.getMethod()); |
| logger.info("Request contextPath: " + request.getContextPath()); |
| logger.info("Request pathInfo: " + request.getPathInfo()); |
| logger.info("Request pathTranslated: " + request.getPathTranslated()); |
| logger.info("Request queryString: " + request.getQueryString()); |
| logger.info("Request requestURI: " + request.getRequestURI()); |
| logger.info("Request requestURL: " + request.getRequestURL()); |
| logger.info("Request servletPath: " + request.getServletPath()); |
| Enumeration<?> headers = request.getHeaderNames(); |
| if (headers != null) { |
| while (headers.hasMoreElements()) { |
| Object headerName = headers.nextElement(); |
| logger.info("Request header " + headerName + ":" + request.getHeader((String)headerName)); |
| } |
| } |
| |
| Enumeration<?> params = request.getParameterNames(); |
| if (params != null) { |
| while (params.hasMoreElements()) { |
| Object paramName = params.nextElement(); |
| logger.info("Request parameter " + paramName + ":" + request.getParameter((String)paramName)); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Send out an error response according to Amazon convention. |
| */ |
| private void faultResponse(HttpServletResponse response, String errorCode, String errorMessage) { |
| try { |
| OutputStreamWriter out = new OutputStreamWriter(response.getOutputStream()); |
| response.setContentType("text/xml; charset=UTF-8"); |
| out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); |
| out.write("<Response><Errors><Error><Code>"); |
| out.write(errorCode); |
| out.write("</Code><Message>"); |
| out.write(errorMessage); |
| out.write("</Message></Error></Errors><RequestID>"); |
| out.write(UUID.randomUUID().toString()); |
| out.write("</RequestID></Response>"); |
| out.flush(); |
| out.close(); |
| } catch (IOException e) { |
| logger.error("Unexpected exception " + e.getMessage(), e); |
| } |
| } |
| |
| /** |
| * Serialize Axis beans to XML output. |
| */ |
| private void serializeResponse(HttpServletResponse response, ADBBean EC2Response) throws ADBException, XMLStreamException, IOException { |
| OutputStream os = response.getOutputStream(); |
| response.setStatus(200); |
| response.setContentType("text/xml"); |
| XMLStreamWriter xmlWriter = xmlOutFactory.createXMLStreamWriter(os); |
| xmlWriter.writeStartDocument("UTF-8", "1.0"); |
| MTOMAwareXMLSerializer MTOMWriter = new MTOMAwareXMLSerializer(xmlWriter); |
| MTOMWriter.setDefaultNamespace("http://ec2.amazonaws.com/doc/" + wsdlVersion + "/"); |
| EC2Response.serialize(null, factory, MTOMWriter); |
| xmlWriter.flush(); |
| xmlWriter.close(); |
| os.close(); |
| } |
| } |