mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
cloudstack api post and ssl fix
Signed-off-by: Sebastien Goasguen <runseb@gmail.com>
This commit is contained in:
parent
fb498a40ba
commit
d5333f4596
@ -1,248 +0,0 @@
|
||||
// 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.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import com.cloud.bridge.service.exception.InternalErrorException;
|
||||
|
||||
/**
|
||||
* JsonAccessor provides the functionality to allow navigating JSON object graph using simple expressions,
|
||||
* for example, following property access expressions are all valid ones
|
||||
*
|
||||
* rootobj.level1obj[1].property
|
||||
* this[0].level1obj[1].property
|
||||
*
|
||||
*/
|
||||
public class JsonAccessor {
|
||||
private JsonElement _json;
|
||||
|
||||
Pattern _arrayAccessorMatcher = Pattern.compile("(.*)\\[(\\d+)\\]");
|
||||
|
||||
public JsonAccessor(JsonElement json) {
|
||||
assert (json != null);
|
||||
_json = json;
|
||||
}
|
||||
|
||||
public BigDecimal getAsBigDecimal(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsBigDecimal();
|
||||
}
|
||||
|
||||
public BigInteger getAsBigInteger(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsBigInteger();
|
||||
}
|
||||
|
||||
public boolean getAsBoolean(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsBoolean();
|
||||
}
|
||||
|
||||
public byte getAsByte(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsByte();
|
||||
}
|
||||
|
||||
public char getAsCharacter(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsCharacter();
|
||||
}
|
||||
|
||||
public double getAsDouble(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsDouble();
|
||||
}
|
||||
|
||||
public float getAsFloat(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsFloat();
|
||||
}
|
||||
|
||||
public int getAsInt(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsInt();
|
||||
}
|
||||
|
||||
public long getAsLong(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsLong();
|
||||
}
|
||||
|
||||
public Number getAsNumber(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsNumber();
|
||||
}
|
||||
|
||||
public short getAsShort(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsShort();
|
||||
}
|
||||
|
||||
public String getAsString(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
return jsonElement.getAsString();
|
||||
}
|
||||
|
||||
public boolean isBoolean(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
if (jsonElement instanceof JsonPrimitive)
|
||||
return ((JsonPrimitive)jsonElement).isBoolean();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isNumber(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
|
||||
if (jsonElement instanceof JsonPrimitive)
|
||||
return ((JsonPrimitive)jsonElement).isNumber();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isString(String propPath) {
|
||||
JsonElement jsonElement = eval(propPath);
|
||||
|
||||
if (jsonElement instanceof JsonPrimitive)
|
||||
return ((JsonPrimitive)jsonElement).isString();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return
|
||||
* -1 : property expression can not be resolved
|
||||
* 0 : match to a null JSON object
|
||||
* 1+ : matched, for array element, the count of the elements inside the array
|
||||
*/
|
||||
public int getMatchCount(String propPath) {
|
||||
JsonElement jsonElement = tryEval(propPath);
|
||||
if (jsonElement == null)
|
||||
return -1;
|
||||
|
||||
if (jsonElement.isJsonNull())
|
||||
return 0;
|
||||
|
||||
if (jsonElement.isJsonArray())
|
||||
return ((JsonArray)jsonElement).size();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public JsonElement eval(String propPath) {
|
||||
JsonElement jsonElement = tryEval(propPath);
|
||||
if (jsonElement == null)
|
||||
throw new InternalErrorException("Property " + propPath + " is resolved to null JSON element on object: " + _json.toString());
|
||||
|
||||
return jsonElement;
|
||||
}
|
||||
|
||||
public JsonElement tryEval(String propPath) {
|
||||
assert (propPath != null);
|
||||
String[] tokens = propPath.split("\\.");
|
||||
|
||||
ArrayList<Resolver> resolverChain = new ArrayList<Resolver>();
|
||||
for (String token : tokens) {
|
||||
Matcher matcher = _arrayAccessorMatcher.matcher(token);
|
||||
if (matcher.find()) {
|
||||
String propStr = matcher.group(1);
|
||||
String indexStr = matcher.group(2);
|
||||
|
||||
resolverChain.add(new ArrayPropertyResolver(propStr, Integer.parseInt(indexStr)));
|
||||
} else {
|
||||
resolverChain.add(new PropertyResolver(token));
|
||||
}
|
||||
}
|
||||
|
||||
JsonElement jsonElementToResolveAt = _json;
|
||||
for (Resolver resolver : resolverChain) {
|
||||
jsonElementToResolveAt = resolver.resolve(jsonElementToResolveAt);
|
||||
|
||||
if (jsonElementToResolveAt == null)
|
||||
break;
|
||||
}
|
||||
|
||||
return jsonElementToResolveAt;
|
||||
}
|
||||
|
||||
//
|
||||
// Property resolvers
|
||||
//
|
||||
private static interface Resolver {
|
||||
public JsonElement resolve(JsonElement jsonElementToResolveAt);
|
||||
}
|
||||
|
||||
private static class PropertyResolver implements Resolver {
|
||||
protected String _propName;
|
||||
|
||||
public PropertyResolver(String propName) {
|
||||
_propName = propName;
|
||||
}
|
||||
|
||||
public JsonElement resolve(JsonElement jsonElementToResolveAt) {
|
||||
if ("this".equals(_propName))
|
||||
return jsonElementToResolveAt;
|
||||
|
||||
if (jsonElementToResolveAt.isJsonObject())
|
||||
return ((JsonObject)jsonElementToResolveAt).get(_propName);
|
||||
|
||||
if (jsonElementToResolveAt.isJsonNull())
|
||||
throw new NullPointerException(String.format("Property %s points to a null element on object: %s", _propName, jsonElementToResolveAt.toString()));
|
||||
|
||||
throw new InternalErrorException("Unable to evaluate JSON accessor property: " + _propName + ", on object: " + jsonElementToResolveAt.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayPropertyResolver extends PropertyResolver {
|
||||
protected int _index;
|
||||
|
||||
public ArrayPropertyResolver(String propName, int index) {
|
||||
super(propName);
|
||||
_index = index;
|
||||
}
|
||||
|
||||
public JsonElement resolve(JsonElement jsonElementToResolveAt) {
|
||||
if (!"this".equals(_propName)) {
|
||||
if (jsonElementToResolveAt.isJsonObject()) {
|
||||
jsonElementToResolveAt = ((JsonObject)jsonElementToResolveAt).get(_propName);
|
||||
} else {
|
||||
if (jsonElementToResolveAt.isJsonNull())
|
||||
throw new NullPointerException(String.format("Property %s points to a null element on object: %s", _propName, jsonElementToResolveAt.toString()));
|
||||
|
||||
throw new InternalErrorException("Unable to evaluate JSON accessor property: " + _propName + ", on object: " + jsonElementToResolveAt.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonElementToResolveAt instanceof JsonArray) {
|
||||
return ((JsonArray)jsonElementToResolveAt).get(_index);
|
||||
}
|
||||
|
||||
if (jsonElementToResolveAt.isJsonNull())
|
||||
throw new NullPointerException(String.format("Property %s points to a null element on object: %s", _propName, jsonElementToResolveAt.toString()));
|
||||
|
||||
throw new InternalErrorException("Unable to evaluate JSON accessor property: " + _propName + ", on object: " + jsonElementToResolveAt.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
45
awsapi/src/com/cloud/bridge/util/JsonElementUtil.java
Normal file
45
awsapi/src/com/cloud/bridge/util/JsonElementUtil.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.cloud.bridge.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*
|
||||
* For more complex cases (JsonArrays or other) it can be rewrite to matcher pattern
|
||||
*/
|
||||
public final class JsonElementUtil {
|
||||
|
||||
private JsonElementUtil() {}
|
||||
|
||||
public static JsonElement getAsJsonElement(final JsonElement jsonElement, final String... path) {
|
||||
JsonElement currentElement = jsonElement;
|
||||
for (final String propertyName : path) {
|
||||
if (currentElement == null) {
|
||||
return null;
|
||||
}
|
||||
if (jsonElement.isJsonObject()) {
|
||||
currentElement = ((JsonObject) currentElement).get(propertyName);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return currentElement;
|
||||
}
|
||||
|
||||
public static Integer getAsInt(final JsonElement jsonElement, final String... path) {
|
||||
final JsonElement targetElement = getAsJsonElement(jsonElement, path);
|
||||
if (targetElement == null || !targetElement.isJsonPrimitive()) {
|
||||
return null;
|
||||
}
|
||||
final JsonPrimitive asPrimitive = (JsonPrimitive) targetElement;
|
||||
return asPrimitive.getAsInt();
|
||||
}
|
||||
|
||||
public static String getAsString(final JsonElement jsonElement, final String... path) {
|
||||
final JsonElement targetElement = getAsJsonElement(jsonElement, path);
|
||||
return targetElement == null ? null : targetElement.getAsString();
|
||||
}
|
||||
|
||||
}
|
||||
21
awsapi/src/com/cloud/stack/CloudStackClientException.java
Normal file
21
awsapi/src/com/cloud/stack/CloudStackClientException.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.cloud.stack;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class CloudStackClientException extends Exception {
|
||||
public CloudStackClientException() {
|
||||
}
|
||||
|
||||
public CloudStackClientException(final String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public CloudStackClientException(final String s, final Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
|
||||
public CloudStackClientException(final Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
@ -1,149 +0,0 @@
|
||||
// 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.stack;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SignatureException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
/**
|
||||
* CloudStackCommand wraps command properties that are being sent to CloudStack
|
||||
*
|
||||
*/
|
||||
public class CloudStackCommand {
|
||||
Map<String, String> _params = new HashMap<String, String>();
|
||||
|
||||
public CloudStackCommand(String cmdName) {
|
||||
this(cmdName, "json");
|
||||
}
|
||||
|
||||
public CloudStackCommand(String cmdName, String responseType) {
|
||||
_params.put("command", cmdName);
|
||||
if (responseType != null)
|
||||
_params.put("response", responseType);
|
||||
}
|
||||
|
||||
public CloudStackCommand setParam(String paramName, String paramValue) {
|
||||
assert (paramName != null);
|
||||
assert (paramValue != null);
|
||||
|
||||
_params.put(paramName, paramValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String signCommand(String apiKey, String secretKey) throws SignatureException {
|
||||
assert (_params.get("command") != null);
|
||||
|
||||
List<String> paramNames = new ArrayList<String>();
|
||||
for (String paramName : _params.keySet())
|
||||
paramNames.add(paramName);
|
||||
|
||||
paramNames.add("apikey");
|
||||
Collections.sort(paramNames);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (String name : paramNames) {
|
||||
String value;
|
||||
if ("apikey".equals(name))
|
||||
value = apiKey;
|
||||
else
|
||||
value = _params.get(name);
|
||||
|
||||
assert (value != null);
|
||||
|
||||
value = urlSafe(value);
|
||||
|
||||
if (sb.length() == 0) {
|
||||
sb.append(name).append("=").append(value);
|
||||
} else {
|
||||
sb.append("&").append(name).append("=").append(value);
|
||||
}
|
||||
}
|
||||
|
||||
String signature = calculateRFC2104HMAC(sb.toString().toLowerCase(), secretKey);
|
||||
return composeQueryString(apiKey, signature);
|
||||
}
|
||||
|
||||
private String composeQueryString(String apiKey, String signature) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String name;
|
||||
String value;
|
||||
|
||||
// treat command specially (although not really necessary )
|
||||
name = "command";
|
||||
value = _params.get(name);
|
||||
if (value != null) {
|
||||
value = urlSafe(value);
|
||||
sb.append(name).append("=").append(value);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : _params.entrySet()) {
|
||||
name = entry.getKey();
|
||||
|
||||
if (!"command".equals(name)) {
|
||||
value = urlSafe(entry.getValue());
|
||||
|
||||
if (sb.length() == 0)
|
||||
sb.append(name).append("=").append(value);
|
||||
else
|
||||
sb.append("&").append(name).append("=").append(value);
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("&apikey=").append(urlSafe(apiKey));
|
||||
sb.append("&signature=").append(urlSafe(signature));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String calculateRFC2104HMAC(String signIt, String secretKey) throws SignatureException {
|
||||
String result = null;
|
||||
try {
|
||||
SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
|
||||
Mac hmacSha1 = Mac.getInstance("HmacSHA1");
|
||||
hmacSha1.init(key);
|
||||
byte[] rawHmac = hmacSha1.doFinal(signIt.getBytes());
|
||||
result = new String(Base64.encodeBase64(rawHmac));
|
||||
} catch (Exception e) {
|
||||
throw new SignatureException("Failed to generate keyed HMAC on soap request: " + e.getMessage());
|
||||
}
|
||||
return result.trim();
|
||||
}
|
||||
|
||||
private String urlSafe(String value) {
|
||||
try {
|
||||
if (value != null)
|
||||
return URLEncoder.encode(value, "UTF-8").replaceAll("\\+", "%20");
|
||||
else
|
||||
return null;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
assert (false);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
118
awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java
Normal file
118
awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java
Normal file
@ -0,0 +1,118 @@
|
||||
// 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.stack;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SignatureException;
|
||||
import java.util.*;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.NameValuePair;
|
||||
import org.apache.commons.httpclient.URI;
|
||||
import org.apache.commons.httpclient.URIException;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
|
||||
/**
|
||||
* CloudStackQueryBuilder wraps command properties that are being sent to CloudStack
|
||||
*/
|
||||
public class CloudStackQueryBuilder {
|
||||
private static final String HMAC_SHA_1 = "HmacSHA1";
|
||||
private static final String COMMAND_KEY = "command";
|
||||
private static final String APIKEY_KEY = "apikey";
|
||||
|
||||
private final Collection<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
|
||||
public CloudStackQueryBuilder(final String commandName) {
|
||||
params.add(new NameValuePair("command", commandName));
|
||||
params.add(new NameValuePair("response", "json"));
|
||||
}
|
||||
|
||||
public static CloudStackQueryBuilder create(final String commandName) {
|
||||
return new CloudStackQueryBuilder(commandName);
|
||||
}
|
||||
|
||||
/**
|
||||
* parameter will be stored to query only if paramValue != null. This assumption is very useful
|
||||
* for optional parameters
|
||||
* @param paramName - not null parameter name
|
||||
* @param paramValue - nullable parameter value
|
||||
*/
|
||||
public CloudStackQueryBuilder addParam(final String paramName, final Object paramValue) {
|
||||
if (paramName == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (paramValue != null) {
|
||||
params.add(new NameValuePair(paramName, String.valueOf(paramValue)));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public HttpMethod buildRequest(final String apiKey, final String secretKey) throws SignatureException {
|
||||
final PostMethod postMethod = new PostMethod();
|
||||
for (final NameValuePair param : params) {
|
||||
postMethod.addParameter(param);
|
||||
}
|
||||
postMethod.addParameter(APIKEY_KEY, apiKey);
|
||||
postMethod.addParameter("signature", calculateSignature(secretKey, apiKey));
|
||||
return postMethod;
|
||||
}
|
||||
|
||||
private String calculateSignature(final String secretKey, final String apiKey) throws SignatureException {
|
||||
final List<NameValuePair> paramsCopy = new ArrayList<NameValuePair>(params.size() + 1);
|
||||
paramsCopy.addAll(params);
|
||||
paramsCopy.add(new NameValuePair(APIKEY_KEY, urlSafe(apiKey)));
|
||||
Collections.sort(paramsCopy, new Comparator<NameValuePair>() {
|
||||
@Override
|
||||
public int compare(final NameValuePair nameValuePair, final NameValuePair nameValuePair2) {
|
||||
return nameValuePair.getName().compareTo(nameValuePair2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
final List<String> serializedParameters = new ArrayList<String>(paramsCopy.size());
|
||||
for (final NameValuePair pair : paramsCopy) {
|
||||
serializedParameters.add(pair.getName() + "=" + urlSafe(pair.getValue()));
|
||||
}
|
||||
final String toSign = StringUtils.join(serializedParameters, "&").toLowerCase();
|
||||
return calculateRFC2104HMAC(toSign, secretKey);
|
||||
}
|
||||
|
||||
private static String calculateRFC2104HMAC(final String signIt, final String secretKey) throws SignatureException {
|
||||
try {
|
||||
final Mac hmacSha1 = Mac.getInstance(HMAC_SHA_1);
|
||||
hmacSha1.init(new SecretKeySpec(secretKey.getBytes(), HMAC_SHA_1));
|
||||
final byte[] rawHmac = hmacSha1.doFinal(signIt.getBytes());
|
||||
return new String(Base64.encodeBase64(rawHmac)).trim();
|
||||
} catch (final Exception e) {
|
||||
throw new SignatureException("Failed to generate keyed HMAC on soap request: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String urlSafe(final String value) {
|
||||
try {
|
||||
return value == null ? null : URLEncoder.encode(value, "UTF-8").replaceAll("\\+", "%20");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
// 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.gate.util;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import com.cloud.bridge.util.JsonAccessor;
|
||||
import com.cloud.gate.testcase.BaseTestCase;
|
||||
import com.cloud.stack.models.CloudStackSnapshot;
|
||||
|
||||
public class JsonAccessorTestCase extends BaseTestCase {
|
||||
protected final static Logger logger = Logger.getLogger(UtilTestCase.class);
|
||||
|
||||
public void testJsonAccessor() {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement json = parser.parse("{firstName: 'Kelven', lastName: 'Yang', arrayObj: [{name: 'elem1'}, {name: 'elem2'}]}");
|
||||
JsonAccessor jsonAccessor = new JsonAccessor(json);
|
||||
|
||||
Assert.assertTrue("Kelven".equals(jsonAccessor.getAsString("firstName")));
|
||||
Assert.assertTrue("Kelven".equals(jsonAccessor.getAsString("this.firstName")));
|
||||
Assert.assertTrue("Yang".equals(jsonAccessor.getAsString("lastName")));
|
||||
Assert.assertTrue("Yang".equals(jsonAccessor.getAsString("this.lastName")));
|
||||
|
||||
Assert.assertTrue("elem1".equals(jsonAccessor.getAsString("arrayObj[0].name")));
|
||||
Assert.assertTrue("elem2".equals(jsonAccessor.getAsString("arrayObj[1].name")));
|
||||
|
||||
Assert.assertTrue("elem1".equals(jsonAccessor.getAsString("this.arrayObj.this[0].name")));
|
||||
Assert.assertTrue("elem2".equals(jsonAccessor.getAsString("this.arrayObj.this[1].name")));
|
||||
|
||||
Assert.assertTrue(jsonAccessor.getMatchCount("firstName") == 1);
|
||||
Assert.assertTrue(jsonAccessor.getMatchCount("middleName") == -1);
|
||||
Assert.assertTrue(jsonAccessor.getMatchCount("arrayObj") == 2);
|
||||
Assert.assertTrue(jsonAccessor.getMatchCount("arrayObj[0]") == 1);
|
||||
}
|
||||
|
||||
public void testGson() {
|
||||
String response =
|
||||
"{ \"queryasyncjobresultresponse\" : {\"jobid\":5868,\"jobstatus\":1,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresulttype\":\"object\",\"jobresult\":{\"snapshot\":{\"id\":3161,\"account\":\"admin\",\"domainid\":1,\"domain\":\"ROOT\",\"snapshottype\":\"MANUAL\",\"volumeid\":186928,\"volumename\":\"KY-DATA-VOL\",\"volumetype\":\"DATADISK\",\"created\":\"2011-06-02T05:05:41-0700\",\"name\":\"i-2-246446-VM_KY-DATA-VOL_20110602120541\",\"intervaltype\":\"MANUAL\",\"state\":\"BackedUp\"}}}}";
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement json = parser.parse(response);
|
||||
JsonAccessor jsonAccessor = new JsonAccessor(json);
|
||||
|
||||
Gson gson = new Gson();
|
||||
CloudStackSnapshot snapshot = gson.fromJson(jsonAccessor.eval("queryasyncjobresultresponse.jobresult.snapshot"), CloudStackSnapshot.class);
|
||||
|
||||
Assert.assertTrue("BackedUp".equals(snapshot.getState()));
|
||||
}
|
||||
}
|
||||
48
awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java
Normal file
48
awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java
Normal file
@ -0,0 +1,48 @@
|
||||
// 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.gate.util;
|
||||
|
||||
import com.cloud.bridge.util.JsonElementUtil;
|
||||
import com.google.gson.JsonArray;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import com.cloud.gate.testcase.BaseTestCase;
|
||||
import com.cloud.stack.models.CloudStackSnapshot;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class JsonElementUtilTestCase extends BaseTestCase {
|
||||
private final static JsonParser JSON_PARSER = new JsonParser();
|
||||
|
||||
public void testJsonElementUtils() {
|
||||
JsonElement json = JSON_PARSER.parse("{firstName: 'Kelven', lastName: 'Yang', arrayObj: [{name: 'elem1'}, {name: 'elem2'}], level1: {level2: 'some'}}");
|
||||
|
||||
assertEquals("Kelven", JsonElementUtil.getAsString(json, "firstName"));
|
||||
assertEquals("Yang", JsonElementUtil.getAsString(json, "lastName"));
|
||||
assertEquals("some", JsonElementUtil.getAsString(json, "level1", "level2"));
|
||||
assertTrue(JsonElementUtil.getAsJsonElement(json, "arrayObj") instanceof JsonArray);
|
||||
}
|
||||
|
||||
public void testGson() {
|
||||
String response = "{ \"queryasyncjobresultresponse\" : {\"jobid\":5868,\"jobstatus\":1,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresulttype\":\"object\",\"jobresult\":{\"snapshot\":{\"id\":3161,\"account\":\"admin\",\"domainid\":1,\"domain\":\"ROOT\",\"snapshottype\":\"MANUAL\",\"volumeid\":186928,\"volumename\":\"KY-DATA-VOL\",\"volumetype\":\"DATADISK\",\"created\":\"2011-06-02T05:05:41-0700\",\"name\":\"i-2-246446-VM_KY-DATA-VOL_20110602120541\",\"intervaltype\":\"MANUAL\",\"state\":\"BackedUp\"}}}}";
|
||||
JsonElement json = JSON_PARSER.parse(response);
|
||||
Gson gson = new Gson();
|
||||
CloudStackSnapshot snapshot = gson.fromJson(JsonElementUtil.getAsJsonElement(json, "queryasyncjobresultresponse", "jobresult", "snapshot"), CloudStackSnapshot.class);
|
||||
Assert.assertTrue("BackedUp".equals(snapshot.getState()));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user