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.joda.time.format.ISODateTimeFormat; 041import org.nuxeo.ecm.core.api.impl.blob.AbstractBlob; 042import org.nuxeo.ecm.platform.audit.api.ExtendedInfo; 043import org.nuxeo.ecm.platform.audit.api.LogEntry; 044import org.nuxeo.ecm.platform.audit.impl.ExtendedInfoImpl; 045import org.nuxeo.ecm.platform.audit.impl.LogEntryImpl; 046import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.BinaryBlobEntrySerializer; 047import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.MapEntrySerializer; 048 049import com.fasterxml.jackson.core.JsonFactory; 050import com.fasterxml.jackson.core.JsonParser; 051import com.fasterxml.jackson.core.JsonToken; 052import com.fasterxml.jackson.core.Version; 053import com.fasterxml.jackson.databind.JsonNode; 054import com.fasterxml.jackson.databind.ObjectMapper; 055import com.fasterxml.jackson.databind.module.SimpleModule; 056 057public class AuditEntryJSONReader { 058 059 public static LogEntry read(String content) throws IOException { 060 061 ObjectMapper objectMapper = new ObjectMapper(); 062 SimpleModule module = new SimpleModule("esAuditJson", Version.unknownVersion()); 063 module.addSerializer(Map.class, new MapEntrySerializer()); 064 module.addSerializer(AbstractBlob.class, new BinaryBlobEntrySerializer()); 065 objectMapper.registerModule(module); 066 067 LogEntryImpl entry = new LogEntryImpl(); 068 069 JsonFactory factory = new JsonFactory(); 070 factory.setCodec(objectMapper); 071 try (JsonParser jp = factory.createParser(content)) { 072 073 JsonToken tok = jp.nextToken(); 074 075 // skip { 076 if (jp.getCurrentToken() == JsonToken.START_OBJECT) { 077 tok = jp.nextToken(); 078 } 079 080 while (tok != null && tok != JsonToken.END_OBJECT) { 081 String key = jp.getCurrentName(); 082 JsonToken token = jp.nextToken(); 083 if (token != JsonToken.VALUE_NULL) { 084 if (LOG_CATEGORY.equals(key)) { 085 entry.setCategory(token == JsonToken.VALUE_NULL ? null : jp.getText()); 086 } else if (LOG_PRINCIPAL_NAME.equals(key)) { 087 entry.setPrincipalName(jp.getText()); 088 } else if (LOG_COMMENT.equals(key)) { 089 entry.setComment(jp.getText()); 090 } else if (LOG_DOC_LIFE_CYCLE.equals(key)) { 091 entry.setDocLifeCycle(jp.getText()); 092 } else if (LOG_DOC_PATH.equals(key)) { 093 entry.setDocPath(jp.getText()); 094 } else if (LOG_DOC_TYPE.equals(key)) { 095 entry.setDocType(jp.getText()); 096 } else if (LOG_DOC_UUID.equals(key)) { 097 entry.setDocUUID(jp.getText()); 098 } else if (LOG_EVENT_ID.equals(key)) { 099 entry.setEventId(jp.getText()); 100 } else if (LOG_REPOSITORY_ID.equals(key)) { 101 entry.setRepositoryId(jp.getText()); 102 } else if (LOG_ID.equals(key)) { 103 entry.setId(jp.getLongValue()); 104 } else if (LOG_EVENT_DATE.equals(key)) { 105 entry.setEventDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate()); 106 } else if (LOG_LOG_DATE.equals(key)) { 107 entry.setLogDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate()); 108 } else if (LOG_EXTENDED.equals(key)) { 109 entry.setExtendedInfos(readExtendedInfo(jp, objectMapper)); 110 } 111 } 112 tok = jp.nextToken(); 113 } 114 } 115 return entry; 116 } 117 118 public static Map<String, ExtendedInfo> readExtendedInfo(JsonParser jp, ObjectMapper objectMapper) 119 throws IOException { 120 121 Map<String, ExtendedInfo> info = new HashMap<>(); 122 123 JsonNode node = jp.readValueAsTree(); 124 125 Iterator<String> fieldsIt = node.fieldNames(); 126 127 while (fieldsIt.hasNext()) { 128 String fieldName = fieldsIt.next(); 129 130 JsonNode field = node.get(fieldName); 131 132 ExtendedInfoImpl ei = null; 133 if (field.isObject() || field.isArray()) { 134 ei = ExtendedInfoImpl.createExtendedInfo(objectMapper.writeValueAsString(field)); 135 } else { 136 if (field.isInt() || field.isLong()) { 137 ei = ExtendedInfoImpl.createExtendedInfo(field.longValue()); 138 } else { 139 ei = ExtendedInfoImpl.createExtendedInfo(field.textValue()); 140 } 141 } 142 info.put(fieldName, ei); 143 } 144 return info; 145 } 146 147}