package perf.test.utils; import static junit.framework.Assert.assertEquals; import java.io.IOException; import java.io.InputStream; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonToken; import org.junit.Test; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Scheduler; import rx.Subscriber; import rx.schedulers.Schedulers; /** * @author Nitesh Kant (nkant@netflix.com) */ public class BackendResponse { private final long responseKey; private final int delay; private final int numItems; private final int itemSize; private final String[] items; public BackendResponse(long responseKey, int delay, int numItems, int itemSize, String[] items) { this.responseKey = responseKey; this.delay = delay; this.numItems = numItems; this.itemSize = itemSize; this.items = items; } public static BackendResponse fromJson(JsonFactory jsonFactory, byte[] content) throws Exception { JsonParser parser = jsonFactory.createJsonParser(content); return parseBackendResponse(parser); } public static BackendResponse fromJson(JsonFactory jsonFactory, String json) throws Exception { JsonParser parser = jsonFactory.createJsonParser(json); return parseBackendResponse(parser); } public static BackendResponse fromJson(JsonFactory jsonFactory, InputStream inputStream) throws JsonParseException { try { JsonParser parser = jsonFactory.createJsonParser(inputStream); return parseBackendResponse(parser); } catch (Exception e) { throw new JsonParseException("Failed to parse JSON", e); } } public static Observable<BackendResponse> fromJsonToObservable(final JsonFactory jsonFactory, final String json) { return fromJsonToObservable(jsonFactory, json, Schedulers.computation()); } public static Observable<BackendResponse> fromJsonToObservable(final JsonFactory jsonFactory, final String json, Scheduler scheduler) { return Observable.create(new OnSubscribe<BackendResponse>() { @Override public void call(Subscriber<? super BackendResponse> o) { try { o.onNext(fromJson(jsonFactory, json)); o.onCompleted(); } catch (Exception e) { o.onError(e); } } }).subscribeOn(scheduler); } public static BackendResponse parseBackendResponse(JsonParser parser) throws IOException { try { // Sanity check: verify that we got "Json Object": if (parser.nextToken() != JsonToken.START_OBJECT) { throw new IOException("Expected data to start with an Object"); } long responseKey = 0; int delay = 0; int numItems = 0; int itemSize = 0; String[] items = null; JsonToken current; while (parser.nextToken() != JsonToken.END_OBJECT) { String fieldName = parser.getCurrentName(); // advance current = parser.nextToken(); if (fieldName.equals("responseKey")) { responseKey = parser.getLongValue(); } else if (fieldName.equals("delay")) { delay = parser.getIntValue(); } else if (fieldName.equals("itemSize")) { itemSize = parser.getIntValue(); } else if (fieldName.equals("numItems")) { numItems = parser.getIntValue(); } else if (fieldName.equals("items")) { // expect numItems to be populated before hitting this if (numItems == 0) { throw new IllegalStateException("Expected numItems > 0"); } items = new String[numItems]; if (current == JsonToken.START_ARRAY) { int j = 0; // For each of the records in the array while (parser.nextToken() != JsonToken.END_ARRAY) { items[j++] = parser.getText(); } } else { // System.out.println("Error: items should be an array: skipping."); parser.skipChildren(); } } } return new BackendResponse(responseKey, delay, numItems, itemSize, items); } finally { parser.close(); } } public long getResponseKey() { return responseKey; } public int getDelay() { return delay; } public int getNumItems() { return numItems; } public int getItemSize() { return itemSize; } public String[] getItems() { return items; } public static class UnitTest { @Test public void testJsonParse() throws Exception { JsonFactory jsonFactory = new JsonFactory(); BackendResponse r = BackendResponse.fromJson(jsonFactory, "{ \"responseKey\": 9999, \"delay\": 50, \"itemSize\": 128, \"numItems\": 2, \"items\": [ \"Lorem\", \"Ipsum\" ]}"); assertEquals(9999, r.getResponseKey()); assertEquals(50, r.getDelay()); assertEquals(128, r.getItemSize()); assertEquals(2, r.getNumItems()); String[] items = r.getItems(); assertEquals(2, items.length); assertEquals("Lorem", items[0]); assertEquals("Ipsum", items[1]); } } }