You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2014/03/26 14:31:46 UTC
[2/2] git commit: updated refs/heads/master to 40f4b37
Revert "cloudstack api post and ssl fix"
This reverts commit d5333f4596460c7123b66ad5c19fc69442696ea2.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/40f4b371
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/40f4b371
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/40f4b371
Branch: refs/heads/master
Commit: 40f4b371b79440868f2b690182079e2692d0f614
Parents: 4251621
Author: Daan Hoogland <da...@onecht.net>
Authored: Wed Mar 26 14:31:18 2014 +0100
Committer: Daan Hoogland <da...@onecht.net>
Committed: Wed Mar 26 14:31:18 2014 +0100
----------------------------------------------------------------------
.../src/com/cloud/bridge/util/JsonAccessor.java | 248 +++++++++++++++++++
.../com/cloud/bridge/util/JsonElementUtil.java | 45 ----
.../cloud/stack/CloudStackClientException.java | 21 --
.../src/com/cloud/stack/CloudStackCommand.java | 149 +++++++++++
.../com/cloud/stack/CloudStackQueryBuilder.java | 118 ---------
.../cloud/gate/util/JsonAccessorTestCase.java | 69 ++++++
.../gate/util/JsonElementUtilTestCase.java | 48 ----
7 files changed, 466 insertions(+), 232 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/src/com/cloud/bridge/util/JsonAccessor.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/bridge/util/JsonAccessor.java b/awsapi/src/com/cloud/bridge/util/JsonAccessor.java
new file mode 100644
index 0000000..2a94dea
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/util/JsonAccessor.java
@@ -0,0 +1,248 @@
+// 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());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/src/com/cloud/bridge/util/JsonElementUtil.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/bridge/util/JsonElementUtil.java b/awsapi/src/com/cloud/bridge/util/JsonElementUtil.java
deleted file mode 100644
index 2d8afb5..0000000
--- a/awsapi/src/com/cloud/bridge/util/JsonElementUtil.java
+++ /dev/null
@@ -1,45 +0,0 @@
-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();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/src/com/cloud/stack/CloudStackClientException.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/stack/CloudStackClientException.java b/awsapi/src/com/cloud/stack/CloudStackClientException.java
deleted file mode 100644
index ac1b3ef..0000000
--- a/awsapi/src/com/cloud/stack/CloudStackClientException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-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);
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/src/com/cloud/stack/CloudStackCommand.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/stack/CloudStackCommand.java b/awsapi/src/com/cloud/stack/CloudStackCommand.java
new file mode 100644
index 0000000..8d6aa68
--- /dev/null
+++ b/awsapi/src/com/cloud/stack/CloudStackCommand.java
@@ -0,0 +1,149 @@
+// 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java b/awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java
deleted file mode 100644
index a7aff68..0000000
--- a/awsapi/src/com/cloud/stack/CloudStackQueryBuilder.java
+++ /dev/null
@@ -1,118 +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.*;
-
-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);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/test/com/cloud/gate/util/JsonAccessorTestCase.java
----------------------------------------------------------------------
diff --git a/awsapi/test/com/cloud/gate/util/JsonAccessorTestCase.java b/awsapi/test/com/cloud/gate/util/JsonAccessorTestCase.java
new file mode 100644
index 0000000..8603e59
--- /dev/null
+++ b/awsapi/test/com/cloud/gate/util/JsonAccessorTestCase.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.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()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40f4b371/awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java
----------------------------------------------------------------------
diff --git a/awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java b/awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java
deleted file mode 100644
index 8b4f267..0000000
--- a/awsapi/test/com/cloud/gate/util/JsonElementUtilTestCase.java
+++ /dev/null
@@ -1,48 +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 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()));
- }
-}