Issue 464: added rough ideas on how to parse new cloudstack 2.2.8 format

This commit is contained in:
Adrian Cole 2011-08-12 17:10:07 +01:00
parent 69e7b101bb
commit 39f4817b66
3 changed files with 207 additions and 32 deletions

View File

@ -0,0 +1,166 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 org.jclouds.json;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test
public class GsonExperimentsTest {
public static final String json = "['hello',5,{name:'GREETINGS',source:'guest'}]";
static class Event {
private String name;
private String source;
private Event(String name, String source) {
this.name = name;
this.source = source;
}
@Override
public String toString() {
return String.format("(name=%s, source=%s)", name, source);
}
}
private Gson gson;
private String json2;
@BeforeTest
void setupSource() {
gson = new Gson();
Collection<Object> collection = new ArrayList<Object>();
collection.add("hello");
collection.add(5);
collection.add(new Event("GREETINGS", "guest"));
json2 = gson.toJson(collection);
assertEquals(json2, "[\"hello\",5,{\"name\":\"GREETINGS\",\"source\":\"guest\"}]");
}
// inspired by
// http://code.google.com/p/google-gson/source/browse/trunk/extras/src/main/java/com/google/gson/extras/examples/rawcollections/RawCollectionsExample.java
public void testRawCollectionsWithParser() {
JsonParser parser = new JsonParser();
JsonArray array = parser.parse(json).getAsJsonArray();
String message = gson.fromJson(array.get(0), String.class);
int number = gson.fromJson(array.get(1), int.class);
Event event = gson.fromJson(array.get(2), Event.class);
assertEquals(message, "hello");
assertEquals(number, 5);
assertEquals(event.toString(), new Event("GREETINGS", "guest").toString());
}
private final String nested = "{ \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] }";
private final String nestedFurther = "{ \"listaccountsresponse\" : { \"count\":1 ,\"event\" : [ {name:'GREETINGS',source:'guest'} ] } }";
// inspired by http://sites.google.com/site/gson/streaming
public void testParseNestedElements() throws IOException {
JsonReader reader = new JsonReader(new StringReader(nested));
List<Event> val = parseThingFromReaderOrNull("event", reader, new TypeLiteral<List<Event>>() {
}.getType());
assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]");
}
public void testParseNestedFurtherElements() throws IOException {
JsonReader reader = new JsonReader(new StringReader(nestedFurther));
List<Event> val = parseThingFromReaderOrNull("event", reader, new TypeLiteral<List<Event>>() {
}.getType());
assertEquals(val.toString(), "[(name=GREETINGS, source=guest)]");
}
protected <T> T parseThingFromReaderOrNull(String toFind, JsonReader reader, Type type) throws IOException {
AtomicReference<String> name = new AtomicReference<String>();
JsonToken token = reader.peek();
for (; token != JsonToken.END_DOCUMENT && nnn(toFind, reader, token, name); token = skipAndPeek(token, reader))
;
T val = gson.fromJson(reader, type);
reader.close();
return val;
}
protected boolean nnn(String toFind, JsonReader reader, JsonToken token, AtomicReference<String> name)
throws IOException {
if (token == JsonToken.NAME) {
String name2 = reader.nextName();
if (toFind.equals(name2)) {
name.set(name2);
return false;
}
}
return true;
}
public JsonToken skipAndPeek(JsonToken token, JsonReader reader) throws IOException {
switch (token) {
case BEGIN_ARRAY:
reader.beginArray();
break;
case END_ARRAY:
reader.endArray();
break;
case BEGIN_OBJECT:
reader.beginObject();
break;
case END_OBJECT:
reader.endObject();
break;
case NAME:
// NOTE that we have already advanced on NAME in the eval block;
break;
case STRING:
reader.nextString();
break;
case NUMBER:
reader.nextString();
break;
case BOOLEAN:
reader.nextBoolean();
break;
case NULL:
reader.nextNull();
break;
case END_DOCUMENT:
break;
}
return reader.peek();
}
}

View File

@ -1,17 +1,17 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2011 Cloud Conscious) LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed 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.
* 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.
* ====================================================================
@ -22,9 +22,9 @@ import java.util.Set;
import org.jclouds.cloudstack.config.CloudStackParserModule;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.domain.Account.State;
import org.jclouds.cloudstack.domain.Account.Type;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
@ -62,41 +62,50 @@ public class ListAccountsResponseTest extends BaseSetParserTest<Account> {
}
@Override
@Unwrap(depth = 2)
@Unwrap(depth = 3, edgeCollection = Set.class)
public Set<Account> expected() {
return ImmutableSet.<Account> of(Account
.builder()
.id(36)
.name("adrian")
.id(505)
.name("jclouds")
.type(Type.USER)
.domainId(1)
.domain("ROOT")
.receivedBytes(0)
.sentBytes(0)
.VMLimit(500l)
.VMs(-3)
.VMsAvailable(503l)
.IPLimit(null)
.domainId(457)
.domain("AA000062-jclouds-dev")
.receivedBytes(318900216)
.sentBytes(23189677)
.VMLimit(15l)
.VMs(1)
.IPsAvailable(14l)
.IPLimit(15l)
.IPs(0)
.IPsAvailable(null)
.volumeLimit(null)
.volumes(0)
.volumesAvailable(null)
.snapshotLimit(null)
.IPsAvailable(15l)
.volumeLimit(90l)
.volumes(2)
.volumesAvailable(88l)
.snapshotLimit(250l)
.snapshots(0)
.snapshotsAvailable(null)
.templateLimit(null)
.snapshotsAvailable(250l)
.templateLimit(15l)
.templates(0)
.templatesAvailable(null)
.templatesAvailable(15l)
.VMsStopped(0)
.VMsRunning(0)
.VMsRunning(1)
.state(State.ENABLED)
.users(
ImmutableSet.of(User.builder().id(46).name("adrian").firstName("Adrian").lastName("test")
.email("adrian@jcloud.com")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-03-26T23:10:49-0700"))
.state("enabled").account("adrian").accountType(Type.USER).domainId(1).domain("ROOT")
.apiKey("APIKEY").secretKey("SECRETKEY").build())).build());
ImmutableSet.of(User.builder()
.id(505)
.name("jclouds")
.firstName("Adrian")
.lastName("Cole")
.email("adrian@jclouds.org")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-04-19T01:57:24+0000"))
.state("enabled")
.account("jclouds")
.accountType(Type.USER)
.domainId(457)
.domain("AA000062-jclouds-dev")
.apiKey("APIKEY")
.secretKey("SECRETKEY").build())).build());
}
}

View File

@ -1 +1 @@
{ "listaccountsresponse" : { "account" : [ {"id":36,"name":"adrian","accounttype":0,"domainid":1,"domain":"ROOT","receivedbytes":0,"sentbytes":0,"vmlimit":"500","vmtotal":-3,"vmavailable":"503","iplimit":"Unlimited","iptotal":0,"ipavailable":"Unlimited","volumelimit":"Unlimited","volumetotal":0,"volumeavailable":"Unlimited","snapshotlimit":"Unlimited","snapshottotal":0,"snapshotavailable":"Unlimited","templatelimit":"Unlimited","templatetotal":0,"templateavailable":"Unlimited","vmstopped":0,"vmrunning":0,"state":"enabled","user":[{"id":46,"username":"adrian","firstname":"Adrian","lastname":"test","email":"adrian@jcloud.com","created":"2011-03-26T23:10:49-0700","state":"enabled","account":"adrian","accounttype":0,"domainid":1,"domain":"ROOT","apikey":"APIKEY","secretkey":"SECRETKEY"}]} ] } }
{ "listaccountsresponse" : { "count":1 ,"account" : [ {"id":505,"name":"jclouds","accounttype":0,"domainid":457,"domain":"AA000062-jclouds-dev","receivedbytes":318900216,"sentbytes":23189677,"vmlimit":"15","vmtotal":1,"vmavailable":"14","iplimit":"15","iptotal":0,"ipavailable":"15","volumelimit":"90","volumetotal":2,"volumeavailable":"88","snapshotlimit":"250","snapshottotal":0,"snapshotavailable":"250","templatelimit":"15","templatetotal":0,"templateavailable":"15","vmstopped":0,"vmrunning":1,"state":"enabled","user":[{"id":505,"username":"jclouds","firstname":"Adrian","lastname":"Cole","email":"adrian@jclouds.org","created":"2011-04-19T01:57:24+0000","state":"enabled","account":"jclouds","accounttype":0,"domainid":457,"domain":"AA000062-jclouds-dev","apikey":"APIKEY","secretkey":"SECRETKEY"}]} ] } }