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 <d...@onecht.net> Authored: Wed Mar 26 14:31:18 2014 +0100 Committer: Daan Hoogland <d...@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())); - } -}