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