/* * Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license. * See LICENSE in the project root for license information. */ package com.linkedin.flashback.serialization; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.linkedin.flashback.scene.Scene; import com.linkedin.flashback.serializable.RecordedByteHttpBody; import com.linkedin.flashback.serializable.RecordedEncodedHttpBody; import com.linkedin.flashback.serializable.RecordedHttpBody; import com.linkedin.flashback.serializable.RecordedHttpExchange; import com.linkedin.flashback.serializable.RecordedHttpMessage; import com.linkedin.flashback.serializable.RecordedHttpRequest; import com.linkedin.flashback.serializable.RecordedHttpResponse; import com.linkedin.flashback.serializable.RecordedStringHttpBody; import java.io.IOException; import java.io.Writer; import java.util.List; import java.util.Map; /** * This class is used for writing, reading scene and serializing{@link com.linkedin.flashback.scene.Scene} * Explicit serialization via Streaming API: http://wiki.fasterxml.com/JacksonInFiveMinutes * * @author shfeng * @author dvinegra */ public class SceneSerializer { private JsonGenerator _jsonGenerator; private static final JsonFactory JSON_FACTORY = new JsonFactory(); public void serialize(Scene scene, Writer writer) throws IOException { _jsonGenerator = JSON_FACTORY.createGenerator(writer); _jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter()); _jsonGenerator.writeStartObject(); _jsonGenerator.writeStringField(SceneSerializationConstant.SCENE_TAG_NAME, scene.getName()); writeHttpExchanges(scene.getRecordedHttpExchangeList()); _jsonGenerator.writeEndObject(); _jsonGenerator.close(); } private void writeHttpExchanges(List<RecordedHttpExchange> recordedHttpExchanges) throws IOException { _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_HTTPEXCHANGE_LIST); int count = 1; for (RecordedHttpExchange recordedHttpExchange : recordedHttpExchanges) { _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_HTTPEXCHANGE + count); writeHttpExchange(recordedHttpExchange); _jsonGenerator.writeEndObject(); count++; } _jsonGenerator.writeEndObject(); } private void writeHttpExchange(RecordedHttpExchange recordedHttpExchanges) throws IOException { _jsonGenerator.writeStringField(SceneSerializationConstant.SCENE_TAG_UPDATE_TIME, recordedHttpExchanges.getUpdateTime().toGMTString()); _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_HTTPREQUEST); writeHttpRequest(recordedHttpExchanges.getRecordedHttpRequest()); _jsonGenerator.writeEndObject(); _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_HTTPRESPONSE); writeHttpResponse(recordedHttpExchanges.getRecordedHttpResponse()); _jsonGenerator.writeEndObject(); } private void writeHttpRequest(RecordedHttpRequest recordedHttpRequest) throws IOException { _jsonGenerator .writeStringField(SceneSerializationConstant.SCENE_TAG_HTTPMETHOD, recordedHttpRequest.getMethod().toString()); _jsonGenerator .writeStringField(SceneSerializationConstant.SCENE_TAG_HTTPURI, recordedHttpRequest.getUri().toString()); writeHttpMessage(recordedHttpRequest); } private void writeHttpResponse(RecordedHttpResponse recordedHttpResponse) throws IOException { _jsonGenerator .writeNumberField(SceneSerializationConstant.SCENE_TAG_HTTPSTATUS_CODE, recordedHttpResponse.getStatus()); writeHttpMessage(recordedHttpResponse); } private void writeHttpMessage(RecordedHttpMessage recordedHttpMessage) throws IOException { if (!recordedHttpMessage.getHeaders().isEmpty()) { writeHttpHeaders(recordedHttpMessage.getHeaders()); } if (recordedHttpMessage.hasHttpBody()) { writeHttpBody(recordedHttpMessage.getHttpBody()); } } private void writeHttpHeaders(Map<String, String> headers) throws IOException { _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_HTTPHEADERS); for (Map.Entry<String, String> entry : headers.entrySet()) { _jsonGenerator.writeStringField(entry.getKey(), entry.getValue()); } _jsonGenerator.writeEndObject(); } private void writeHttpBody(RecordedHttpBody httpBody) throws IOException { if (httpBody instanceof RecordedEncodedHttpBody) { _jsonGenerator.writeObjectFieldStart(SceneSerializationConstant.SCENE_TAG_ENCODED_HTTPBODY); _jsonGenerator.writeStringField(SceneSerializationConstant.SCENE_TAG_HTTPBODY_ENCODING, ((RecordedEncodedHttpBody) httpBody).getEncodingName()); writeHttpBody(((RecordedEncodedHttpBody) httpBody).getDecodedBody()); _jsonGenerator.writeEndObject(); } else if (httpBody instanceof RecordedStringHttpBody) { _jsonGenerator.writeStringField(SceneSerializationConstant.SCENE_TAG_STRING_HTTPBODY, ((RecordedStringHttpBody) httpBody).getContent()); } else { _jsonGenerator.writeBinaryField(SceneSerializationConstant.SCENE_TAG_BINARY_HTTPBODY, ((RecordedByteHttpBody) httpBody).getContent()); } } }