001/* 002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.elasticsearch.audit.io; 020 021import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_CATEGORY; 022import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_COMMENT; 023import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_LIFE_CYCLE; 024import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_PATH; 025import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_TYPE; 026import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_UUID; 027import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EVENT_DATE; 028import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EVENT_ID; 029import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EXTENDED; 030import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_ID; 031import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_LOG_DATE; 032import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_PRINCIPAL_NAME; 033import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_REPOSITORY_ID; 034 035import java.io.IOException; 036import java.util.HashMap; 037import java.util.Iterator; 038import java.util.Map; 039 040import org.codehaus.jackson.JsonFactory; 041import org.codehaus.jackson.JsonNode; 042import org.codehaus.jackson.JsonParser; 043import org.codehaus.jackson.JsonToken; 044import org.codehaus.jackson.map.ObjectMapper; 045import org.codehaus.jackson.map.module.SimpleModule; 046import org.joda.time.format.ISODateTimeFormat; 047import org.nuxeo.ecm.core.api.impl.blob.AbstractBlob; 048import org.nuxeo.ecm.platform.audit.api.ExtendedInfo; 049import org.nuxeo.ecm.platform.audit.api.LogEntry; 050import org.nuxeo.ecm.platform.audit.impl.ExtendedInfoImpl; 051import org.nuxeo.ecm.platform.audit.impl.LogEntryImpl; 052import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.BinaryBlobEntrySerializer; 053import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.MapEntrySerializer; 054 055public class AuditEntryJSONReader { 056 057 public static LogEntry read(String content) throws IOException { 058 059 ObjectMapper objectMapper = new ObjectMapper(); 060 SimpleModule module = new SimpleModule("esAuditJson", org.codehaus.jackson.Version.unknownVersion()); 061 module.addSerializer(Map.class, new MapEntrySerializer()); 062 module.addSerializer(AbstractBlob.class, new BinaryBlobEntrySerializer()); 063 objectMapper.registerModule(module); 064 065 JsonFactory factory = new JsonFactory(); 066 factory.setCodec(objectMapper); 067 JsonParser jp = factory.createJsonParser(content); 068 069 JsonToken tok = jp.nextToken(); 070 071 // skip { 072 if (jp.getCurrentToken() == JsonToken.START_OBJECT) { 073 tok = jp.nextToken(); 074 } 075 076 LogEntryImpl entry = new LogEntryImpl(); 077 078 while (tok != null && tok != JsonToken.END_OBJECT) { 079 String key = jp.getCurrentName(); 080 JsonToken token = jp.nextToken(); 081 if (token != JsonToken.VALUE_NULL) { 082 if (LOG_CATEGORY.equals(key)) { 083 entry.setCategory(token == JsonToken.VALUE_NULL ? null : jp.getText()); 084 } else if (LOG_PRINCIPAL_NAME.equals(key)) { 085 entry.setPrincipalName(jp.getText()); 086 } else if (LOG_COMMENT.equals(key)) { 087 entry.setComment(jp.getText()); 088 } else if (LOG_DOC_LIFE_CYCLE.equals(key)) { 089 entry.setDocLifeCycle(jp.getText()); 090 } else if (LOG_DOC_PATH.equals(key)) { 091 entry.setDocPath(jp.getText()); 092 } else if (LOG_DOC_TYPE.equals(key)) { 093 entry.setDocType(jp.getText()); 094 } else if (LOG_DOC_UUID.equals(key)) { 095 entry.setDocUUID(jp.getText()); 096 } else if (LOG_EVENT_ID.equals(key)) { 097 entry.setEventId(jp.getText()); 098 } else if (LOG_REPOSITORY_ID.equals(key)) { 099 entry.setRepositoryId(jp.getText()); 100 } else if (LOG_ID.equals(key)) { 101 entry.setId(jp.getLongValue()); 102 } else if (LOG_EVENT_DATE.equals(key)) { 103 entry.setEventDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate()); 104 } else if (LOG_LOG_DATE.equals(key)) { 105 entry.setLogDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate()); 106 } else if (LOG_EXTENDED.equals(key)) { 107 entry.setExtendedInfos(readExtendedInfo(entry, jp, objectMapper)); 108 } 109 } 110 tok = jp.nextToken(); 111 } 112 return entry; 113 } 114 115 public static Map<String, ExtendedInfo> readExtendedInfo(LogEntryImpl entry, JsonParser jp, 116 ObjectMapper objectMapper) throws IOException { 117 118 Map<String, ExtendedInfo> info = new HashMap<String, ExtendedInfo>(); 119 120 JsonNode node = jp.readValueAsTree(); 121 122 Iterator<String> fieldsIt = node.getFieldNames(); 123 124 while (fieldsIt.hasNext()) { 125 String fieldName = fieldsIt.next(); 126 127 JsonNode field = node.get(fieldName); 128 129 ExtendedInfoImpl ei = null; 130 if (field.isObject() || field.isArray()) { 131 ei = ExtendedInfoImpl.createExtendedInfo(objectMapper.writeValueAsString(field)); 132 } else { 133 if (field.isInt() || field.isLong()) { 134 ei = ExtendedInfoImpl.createExtendedInfo(field.getLongValue()); 135 } else { 136 ei = ExtendedInfoImpl.createExtendedInfo(field.getTextValue()); 137 } 138 } 139 info.put(fieldName, ei); 140 } 141 return info; 142 } 143 144}