/* * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * Thierry Delprat */ package org.nuxeo.elasticsearch.audit.io; import java.io.IOException; import java.io.Serializable; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.JsonSerializer; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.module.SimpleModule; import org.joda.time.DateTime; import org.joda.time.format.ISODateTimeFormat; import org.nuxeo.ecm.core.api.impl.blob.AbstractBlob; import org.nuxeo.ecm.platform.audit.api.ExtendedInfo; import org.nuxeo.ecm.platform.audit.api.LogEntry; import com.fasterxml.jackson.core.JsonProcessingException; public class AuditEntryJSONWriter { protected static final Log log = LogFactory.getLog(AuditEntryJSONWriter.class); public static void asJSON(JsonGenerator jg, LogEntry logEntry) throws IOException { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule("esAuditJson", org.codehaus.jackson.Version.unknownVersion()); module.addSerializer(Map.class, new MapEntrySerializer()); module.addSerializer(AbstractBlob.class, new BinaryBlobEntrySerializer()); objectMapper.registerModule(module); jg.setCodec(objectMapper); jg.writeStartObject(); jg.writeStringField("entity-type", "logEntry"); writeField(jg, "category", logEntry.getCategory()); writeField(jg, "principalName", logEntry.getPrincipalName()); writeField(jg, "comment", logEntry.getComment()); writeField(jg, "docLifeCycle", logEntry.getDocLifeCycle()); writeField(jg, "docPath", logEntry.getDocPath()); writeField(jg, "docType", logEntry.getDocType()); writeField(jg, "docUUID", logEntry.getDocUUID()); writeField(jg, "eventId", logEntry.getEventId()); writeField(jg, "repositoryId", logEntry.getRepositoryId()); jg.writeStringField("eventDate", ISODateTimeFormat.dateTime().print(new DateTime(logEntry.getEventDate()))); jg.writeNumberField("id", logEntry.getId()); jg.writeStringField("logDate", ISODateTimeFormat.dateTime().print(new DateTime(logEntry.getLogDate()))); Map<String, ExtendedInfo> extended = logEntry.getExtendedInfos(); jg.writeObjectFieldStart("extended"); for (String key : extended.keySet()) { ExtendedInfo ei = extended.get(key); if (ei != null && ei.getSerializableValue() != null) { Serializable value = ei.getSerializableValue(); if (value instanceof String) { String strValue = (String) value; if (isJsonContent(strValue)) { jg.writeFieldName(key); jg.writeRawValue(strValue); } else { jg.writeStringField(key, strValue); } } else { try { jg.writeObjectField(key, ei.getSerializableValue()); } catch (JsonMappingException e) { log.error("No Serializer found.", e); } } } else { jg.writeNullField(key); } } jg.writeEndObject(); jg.writeEndObject(); jg.flush(); } /** * Helper method used to determine if a String field is actually nested JSON * * @since 7.4 */ protected static boolean isJsonContent(String value) { if (value != null) { value = value.trim(); if (value.startsWith("{") && value.endsWith("}")) { return true; } else if (value.startsWith("[") && value.endsWith("]")) { return true; } } return false; } protected static void writeField(JsonGenerator jg, String name, String value) throws IOException { if (value == null) { jg.writeNullField(name); } else { jg.writeStringField(name, value); } } static class MapEntrySerializer extends JsonSerializer<Map> { @Override public void serialize(Map map, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); for (Object key : map.keySet()) { jgen.writeObjectField((String) key, map.get(key)); } jgen.writeEndObject(); } } static class BinaryBlobEntrySerializer extends JsonSerializer<AbstractBlob> { @Override public void serialize(AbstractBlob blob, JsonGenerator jgen, SerializerProvider provider) throws JsonGenerationException, IOException { // Do not serizalize jgen.writeNull(); } } }