Repository: cloudstack
Updated Branches:
refs/heads/volume-upload 36c0c38ab -> 9bb6cf845
volume upload: persisting the volume metadata
on calling GetUploadParamsForVolume, persisting the metadata to db
validating the account limits and incrementing the appropriate limits
encoded the metadata on management server using preshared key
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/9bb6cf84
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/9bb6cf84
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/9bb6cf84
Branch: refs/heads/volume-upload
Commit: 9bb6cf845284deaabb5e2ea8896cbb10b5935513
Parents: 36c0c38
Author: Rajani Karuturi <[email protected]>
Authored: Thu Dec 18 17:50:51 2014 +0530
Committer: Rajani Karuturi <[email protected]>
Committed: Thu Dec 18 17:50:51 2014 +0530
----------------------------------------------------------------------
api/src/com/cloud/storage/VolumeApiService.java | 6 ++
.../volume/GetUploadParamsForVolumeCmd.java | 17 ++-
.../TemplateOrVolumePostUploadCommand.java | 13 +--
.../subsystem/api/storage/VolumeService.java | 2 +
.../storage/volume/VolumeServiceImpl.java | 14 +++
.../com/cloud/storage/VolumeApiServiceImpl.java | 103 +++++++++++++++++--
.../com/cloud/template/TemplateManagerImpl.java | 39 +++----
utils/pom.xml | 13 ---
utils/src/com/cloud/utils/EncryptionUtil.java | 69 +++++++++++++
9 files changed, 213 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/api/src/com/cloud/storage/VolumeApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/VolumeApiService.java
b/api/src/com/cloud/storage/VolumeApiService.java
index 5487a4b..7ed1516 100644
--- a/api/src/com/cloud/storage/VolumeApiService.java
+++ b/api/src/com/cloud/storage/VolumeApiService.java
@@ -22,6 +22,7 @@ import
org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import
org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
@@ -29,6 +30,9 @@ import
org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.user.Account;
+import org.apache.cloudstack.api.response.GetUploadParamsResponse;
+
+import java.net.MalformedURLException;
public interface VolumeApiService {
/**
@@ -72,6 +76,8 @@ public interface VolumeApiService {
*/
Volume uploadVolume(UploadVolumeCmd cmd) throws
ResourceAllocationException;
+ GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd)
throws ResourceAllocationException, MalformedURLException;
+
boolean deleteVolume(long volumeId, Account caller) throws
ConcurrentOperationException;
Volume attachVolumeToVM(AttachVolumeCmd command);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
----------------------------------------------------------------------
diff --git
a/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
b/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
index d6f5c7d..1342ffc 100644
---
a/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
+++
b/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
@@ -19,9 +19,8 @@
package org.apache.cloudstack.api.command.user.volume;
import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.UUID;
+import com.cloud.exception.ResourceAllocationException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.AbstractGetUploadParamsCmd;
import org.apache.cloudstack.api.ApiConstants;
@@ -57,18 +56,14 @@ public class GetUploadParamsForVolumeCmd extends
AbstractGetUploadParamsCmd {
@Override
public void execute() throws ServerApiException {
- // TODO Auto-generated method stub
+
try {
- GetUploadParamsResponse response = createGetUploadParamsResponse(
- UUID.fromString("C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"),
- new
URL("https://1-2-3-4.xyz.com/upload/C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"),
-
"TKPFeuz2nHmE/kcREEu24mnj1MrLdzOeJIHXR9HLIGgk56bkRJHaD0RRL2lds1rKKhrro4/PuleEh4YhRinhxaAmPpU4e55eprG8gTCX0ItyFAtlZViVdKXMew5Dfp4Qg8W9I1/IsDJd2Kas9/ftDQLiemAlPt0uS7Ou6asOCpifnBaKvhM4UGEjHSnni1KhBzjgEyDW3Y42HKJSSv58Sgmxl9LCewBX8vtn9tXKr+j4afj7Jlh7DFhyo9HOPC5ogR4hPBKqP7xF9tHxAyq6YqfBzsng3Xwe+Pb8TU1kFHg1l2DM4tY6ooW2h8lOhWUkrJu4hOAOeTeRtCjW3H452NKoeA1M8pKWuqMo5zRMti2u2hNZs0YY2yOy8oWMMG+lG0hvIlajqEU=",
- "2014-10-17T12:00:00+0530",
"de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9");
+ GetUploadParamsResponse response =
_volumeService.uploadVolume(this);
response.setResponseName(getCommandName());
setResponseObject(response);
-
- } catch (MalformedURLException e) {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
"malformedurl exception: " + e.getMessage());
+ } catch (MalformedURLException | ResourceAllocationException e) {
+ s_logger.error("exception while uploading volume", e);
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
"exception while uploading a volume: " + e.getMessage());
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
----------------------------------------------------------------------
diff --git
a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
index de943c4..d2a9577 100644
---
a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
+++
b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
@@ -31,6 +31,9 @@ public class TemplateOrVolumePostUploadCommand {
this.endPoint = endPoint;
}
+ public TemplateOrVolumePostUploadCommand() {
+ }
+
public DataObject getDataObject() {
return dataObject;
}
@@ -56,7 +59,7 @@ public class TemplateOrVolumePostUploadCommand {
return false;
}
- TemplateOrVolumePostUploadCommand that =
(TemplateOrVolumePostUploadCommand) o;
+ TemplateOrVolumePostUploadCommand that =
(TemplateOrVolumePostUploadCommand)o;
return dataObject.equals(that.dataObject) &&
endPoint.equals(that.endPoint);
@@ -69,10 +72,8 @@ public class TemplateOrVolumePostUploadCommand {
return result;
}
- @Override public String toString() {
- return "TemplateOrVolumePostUploadCommand{" +
- "dataObject=" + dataObject +
- ", endPoint=" + endPoint +
- '}';
+ @Override
+ public String toString() {
+ return "TemplateOrVolumePostUploadCommand{" + "dataObject=" +
dataObject + ", endPoint=" + endPoint + '}';
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
----------------------------------------------------------------------
diff --git
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
index 171e9df..d9a75cc 100644
---
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
+++
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
@@ -94,6 +94,8 @@ public interface VolumeService {
AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume,
DataStore store);
+ public EndPoint registerVolumeForPostUpload(VolumeInfo volume, DataStore
store);
+
AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
void resizeVolumeOnHypervisor(long volumeId, long newSize, long
destHostId, String instanceName);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index edb50b2..5d23ffe 100644
---
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -1223,6 +1223,20 @@ public class VolumeServiceImpl implements VolumeService {
return future;
}
+ @Override
+ public EndPoint registerVolumeForPostUpload(VolumeInfo volume, DataStore
store) {
+ DataObject volumeOnStore = store.create(volume);
+
+ volumeOnStore.processEvent(Event.CreateOnlyRequested);
+
+ EndPoint ep = _epSelector.select(store);
+ if (ep == null) {
+ s_logger.warn("There is no secondary storage VM for image store "
+ store.getName());
+ return null;
+ }
+ return ep;
+ }
+
protected Void
registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl,
CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
CreateCmdResult result = callback.getResult();
try {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index a6c6ca7..5f15e3a 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -16,7 +16,10 @@
// under the License.
package com.cloud.storage;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -26,6 +29,15 @@ import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
+import com.cloud.utils.EncryptionUtil;
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import
org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
+import org.apache.cloudstack.api.response.GetUploadParamsResponse;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
@@ -146,6 +158,8 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
public class VolumeApiServiceImpl extends ManagerBase implements
VolumeApiService, VmWorkJobHandler {
private final static Logger s_logger =
Logger.getLogger(VolumeApiServiceImpl.class);
@@ -261,6 +275,70 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
return volume;
}
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription
= "uploading volume for post upload", async = true)
+ public GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd
cmd) throws ResourceAllocationException, MalformedURLException {
+ Account caller = CallContext.current().getCallingAccount();
+ long ownerId = cmd.getEntityOwnerId();
+ Account owner = _entityMgr.findById(Account.class, ownerId);
+ Long zoneId = cmd.getZoneId();
+ String volumeName = cmd.getName();
+ String format = cmd.getFormat();
+ Long diskOfferingId = cmd.getDiskOfferingId();
+ String imageStoreUuid = cmd.getImageStoreUuid();
+ DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
+
+ validateVolume(caller, ownerId, zoneId, volumeName, null, format,
diskOfferingId);
+
+ VolumeVO volume = persistVolume(owner, zoneId, volumeName, null,
cmd.getFormat(), diskOfferingId);
+
+ VolumeInfo vol = volFactory.getVolume(volume.getId());
+
+ RegisterVolumePayload payload = new RegisterVolumePayload(null,
cmd.getChecksum(), cmd.getFormat());
+ vol.addPayload(payload);
+
+ EndPoint ep = volService.registerVolumeForPostUpload(vol, store);
+
+ TemplateOrVolumePostUploadCommand command = new
TemplateOrVolumePostUploadCommand(vol, ep);
+
+ GetUploadParamsResponse response = new GetUploadParamsResponse();
+ String url = "https://" + command.getEndPoint().getPublicAddr() +
"/upload/" + command.getDataObject().getUuid();
+ response.setPostURL(new URL(url));
+
+ response.setId(UUID.fromString(command.getDataObject().getUuid()));
+
+ /*
+ * TODO: hardcoding the timeout to current + 60 min for now. This
needs to goto the database
+ */
+ DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
+ currentDateTime.plusHours(1);
+ String expires = currentDateTime.toString();
+ response.setTimeout(expires);
+
+ String key = _configDao.getValue(Config.SSVMPSK.key());
+ /*
+ * encoded metadata using the post upload config ssh key
+ */
+ final List<String> fieldExclusions = Arrays.asList("s_logger");
+ Gson gson = new GsonBuilder().setExclusionStrategies(new
ExclusionStrategy() {
+ @Override public boolean shouldSkipField(FieldAttributes f) {
+ return f.getDeclaringClass() == Logger.class;
+ }
+ @Override public boolean shouldSkipClass(Class<?> clazz) {
+ return false;
+ }
+ }).create();
+ String jsonPayload = gson.toJson(command);
+ response.setMetadata(EncryptionUtil.encodeData(jsonPayload, key));
+
+ /*
+ * signature calculated on the url, expiry, metadata.
+ */
+ response.setSignature(EncryptionUtil.generateSignature(jsonPayload +
url + expires, key));
+ return response;
+ }
+
private boolean validateVolume(Account caller, long ownerId, Long zoneId,
String volumeName, String url,
String format, Long diskOfferingId) throws
ResourceAllocationException {
@@ -282,8 +360,16 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
throw new PermissionDeniedException("Cannot perform this
operation, Zone is currently disabled: " + zoneId);
}
- if (url.toLowerCase().contains("file://")) {
- throw new InvalidParameterValueException("File:// type urls are
currently unsupported");
+ //validating the url only when url is not null. url can be null incase
of form based post upload
+ if (url != null ) {
+ if( url.toLowerCase().contains("file://")) {
+ throw new InvalidParameterValueException("File:// type urls
are currently unsupported");
+ }
+ UriUtils.validateUrl(format, url);
+ // Check that the resource limit for secondary storage won't be
exceeded
+
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+ } else {
+
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId),
ResourceType.secondary_storage);
}
ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
@@ -291,12 +377,6 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
throw new IllegalArgumentException("Image format is incorrect " +
format + ". Supported formats are " +
EnumUtils.listValues(ImageFormat.values()));
}
- UriUtils.validateUrl(format, url);
-
-
- // Check that the resource limit for secondary storage won't be
exceeded
- _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
-
// Check that the the disk offering specified is valid
if (diskOfferingId != null) {
DiskOfferingVO diskOffering =
_diskOfferingDao.findById(diskOfferingId);
@@ -357,7 +437,12 @@ public class VolumeApiServiceImpl extends ManagerBase
implements VolumeApiServic
// Increment resource count during allocation; if actual
creation fails,
// decrement it
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.volume);
-
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+ //url can be null incase of postupload
+ if(url!=null) {
+
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+ } else {
+
_resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
ResourceType.secondary_storage);
+ }
return volume;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java
b/server/src/com/cloud/template/TemplateManagerImpl.java
index 2185986..53fb00d 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -19,8 +19,6 @@ package com.cloud.template;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -31,17 +29,18 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.utils.EncryptionUtil;
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import
org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
-import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
@@ -363,17 +362,25 @@ public class TemplateManagerImpl extends ManagerBase
implements TemplateManager,
String expires = currentDateTime.toString();
response.setTimeout(expires);
+ String key = _configDao.getValue(Config.SSVMPSK.key());
/*
* encoded metadata using the post upload config ssh key
*/
- Gson gson = new Gson();
+ Gson gson = new GsonBuilder().setExclusionStrategies(new
ExclusionStrategy() {
+ @Override public boolean shouldSkipField(FieldAttributes f) {
+ return
f.getDeclaredType().getClass().isInstance(Logger.class);
+ }
+ @Override public boolean shouldSkipClass(Class<?> clazz) {
+ return false;
+ }
+ }).create();
String jsonPayload = gson.toJson(payload);
- response.setMetadata(encodeData(jsonPayload));
+ response.setMetadata(EncryptionUtil.encodeData(jsonPayload, key));
/*
* signature calculated on the url, expiry, metadata.
*/
- response.setSignature(encodeData(jsonPayload+url+expires));
+ response.setSignature(EncryptionUtil.generateSignature(jsonPayload
+ url + expires, key));
return response;
} else {
@@ -381,22 +388,6 @@ public class TemplateManagerImpl extends ManagerBase
implements TemplateManager,
}
}
- private String encodeData(String data) {
- String key = _configDao.getValue(Config.SSVMPSK.key());
-
- try {
- final Mac mac = Mac.getInstance("HmacSHA1");
- final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),
"HmacSHA1");
- mac.init(keySpec);
- mac.update(data.getBytes());
- final byte[] encryptedBytes = mac.doFinal();
- final String computedSignature =
Base64.encodeBase64String(encryptedBytes);
- return computedSignature;
- } catch (NoSuchAlgorithmException | InvalidKeyException e) {
- s_logger.error("exception occured which encoding the data.", e);
- return null;
- }
- }
@Override
public DataStore getImageStore(String storeUuid, Long zoneId) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/utils/pom.xml
----------------------------------------------------------------------
diff --git a/utils/pom.xml b/utils/pom.xml
index 0bf940c..2f1fa40 100755
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -183,19 +183,6 @@
</excludes>
</configuration>
</plugin>
- <plugin>
- <groupId>com.mycila</groupId>
- <artifactId>license-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>cloudstack-checklicence</id>
- <phase>process-classes</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
<resources>
<resource>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9bb6cf84/utils/src/com/cloud/utils/EncryptionUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/EncryptionUtil.java
b/utils/src/com/cloud/utils/EncryptionUtil.java
new file mode 100644
index 0000000..28d781f
--- /dev/null
+++ b/utils/src/com/cloud/utils/EncryptionUtil.java
@@ -0,0 +1,69 @@
+/*
+ * 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.utils;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+import org.jasypt.encryption.pbe.PBEStringEncryptor;
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+public class EncryptionUtil {
+ public static final Logger s_logger =
Logger.getLogger(EncryptionUtil.class.getName());
+ private static PBEStringEncryptor encryptor;
+
+ private static void initialize(String key) {
+ StandardPBEStringEncryptor standardPBEStringEncryptor = new
StandardPBEStringEncryptor();
+ standardPBEStringEncryptor.setAlgorithm("PBEWITHSHA1ANDDESEDE");
+ standardPBEStringEncryptor.setPassword(key);
+ encryptor = standardPBEStringEncryptor;
+ }
+
+ public static String encodeData(String data, String key) {
+ if (encryptor == null) {
+ initialize(key);
+ }
+ return encryptor.encrypt(data);
+ }
+
+ public static String decodeData(String encodedData, String key) {
+ if (encryptor == null) {
+ initialize(key);
+ }
+ return encryptor.decrypt(encodedData);
+ }
+
+ public static String generateSignature(String data, String key) {
+ try {
+ final Mac mac = Mac.getInstance("HmacSHA1");
+ final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(),
"HmacSHA1");
+ mac.init(keySpec);
+ mac.update(data.getBytes());
+ final byte[] encryptedBytes = mac.doFinal();
+ return Base64.encodeBase64String(encryptedBytes);
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ s_logger.error("exception occurred which encoding the data.", e);
+ return null;
+ }
+ }
+}