001/* 002 * (C) Copyright 2006-2017 Nuxeo (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 * Nuxeo - initial API and implementation 018 */ 019package org.nuxeo.ecm.platform.audit.service; 020 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.HashSet; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.platform.audit.api.DocumentHistoryReader; 031import org.nuxeo.ecm.platform.audit.api.document.DocumentHistoryReaderImpl; 032import org.nuxeo.ecm.platform.audit.service.extension.AdapterDescriptor; 033import org.nuxeo.ecm.platform.audit.service.extension.AuditBackendDescriptor; 034import org.nuxeo.ecm.platform.audit.service.extension.AuditBulkerDescriptor; 035import org.nuxeo.ecm.platform.audit.service.extension.EventDescriptor; 036import org.nuxeo.ecm.platform.audit.service.extension.ExtendedInfoDescriptor; 037import org.nuxeo.runtime.model.ComponentContext; 038import org.nuxeo.runtime.model.ComponentInstance; 039import org.nuxeo.runtime.model.ComponentName; 040import org.nuxeo.runtime.model.DefaultComponent; 041 042/** 043 * Event service configuration. 044 * 045 * @author <a href="mailto:ja@nuxeo.com">Julien Anguenot</a> 046 */ 047public class NXAuditEventsService extends DefaultComponent { 048 049 public static final ComponentName NAME = new ComponentName( 050 "org.nuxeo.ecm.platform.audit.service.NXAuditEventsService"); 051 052 private static final String EVENT_EXT_POINT = "event"; 053 054 private static final String EXTENDED_INFO_EXT_POINT = "extendedInfo"; 055 056 private static final String ADAPTER_POINT = "adapter"; 057 058 /** 059 * If passed as true on the event properties, event not logged 060 * 061 * @since 5.7 062 */ 063 public static final String DISABLE_AUDIT_LOGGER = "disableAuditLogger"; 064 065 private static final String BACKEND_EXT_POINT = "backend"; 066 067 protected static final Log log = LogFactory.getLog(NXAuditEventsService.class); 068 069 protected final Set<ExtendedInfoDescriptor> extendedInfoDescriptors = new HashSet<>(); 070 071 protected final Map<String, List<ExtendedInfoDescriptor>> eventExtendedInfoDescriptors = new HashMap<>(); 072 073 // the adapters that will injected in the EL context for extended 074 // information 075 protected final Set<AdapterDescriptor> documentAdapters = new HashSet<>(); 076 077 protected final Set<String> eventNames = new HashSet<>(); 078 079 protected AuditBackend backend; 080 081 protected AuditBackendDescriptor backendConfig = new AuditBackendDescriptor(); 082 083 protected AuditBulker bulker; 084 085 protected AuditBulkerDescriptor bulkerConfig = new AuditBulkerDescriptor(); 086 087 @Override 088 public int getApplicationStartedOrder() { 089 return backendConfig.getApplicationStartedOrder(); 090 } 091 092 @Override 093 public void start(ComponentContext context) { 094 backend = backendConfig.newInstance(this); 095 backend.onApplicationStarted(); 096 bulker = bulkerConfig.newInstance(backend); 097 bulker.onApplicationStarted(); 098 } 099 100 @Override 101 public void stop(ComponentContext context) { 102 try { 103 bulker.onApplicationStopped(); 104 } finally { 105 backend.onApplicationStopped(); 106 } 107 } 108 109 protected void doRegisterAdapter(AdapterDescriptor desc) { 110 if (log.isDebugEnabled()) { 111 log.debug("Registered adapter : " + desc.getName()); 112 } 113 documentAdapters.add(desc); 114 } 115 116 protected void doRegisterEvent(EventDescriptor desc) { 117 String eventName = desc.getName(); 118 boolean eventEnabled = desc.getEnabled(); 119 if (eventEnabled) { 120 eventNames.add(eventName); 121 if (log.isDebugEnabled()) { 122 log.debug("Registered event: " + eventName); 123 } 124 for (ExtendedInfoDescriptor extInfoDesc : desc.getExtendedInfoDescriptors()) { 125 if (extInfoDesc.getEnabled()) { 126 if (eventExtendedInfoDescriptors.containsKey(eventName)) { 127 eventExtendedInfoDescriptors.get(eventName).add(extInfoDesc); 128 } else { 129 List<ExtendedInfoDescriptor> toBeAdded = new ArrayList<>(); 130 toBeAdded.add(extInfoDesc); 131 eventExtendedInfoDescriptors.put(eventName, toBeAdded); 132 } 133 } else { 134 if (eventExtendedInfoDescriptors.containsKey(eventName)) { 135 eventExtendedInfoDescriptors.get(eventName).remove(extInfoDesc); 136 } 137 } 138 } 139 } else if (eventNames.contains(eventName) && !eventEnabled) { 140 doUnregisterEvent(desc); 141 } 142 } 143 144 protected void doRegisterExtendedInfo(ExtendedInfoDescriptor desc) { 145 if (log.isDebugEnabled()) { 146 log.debug("Registered extended info mapping : " + desc.getKey()); 147 } 148 extendedInfoDescriptors.add(desc); 149 } 150 151 protected void doUnregisterAdapter(AdapterDescriptor desc) { 152 // FIXME: this doesn't look right 153 documentAdapters.remove(desc.getName()); 154 if (log.isDebugEnabled()) { 155 log.debug("Unregistered adapter: " + desc.getName()); 156 } 157 } 158 159 protected void doUnregisterEvent(EventDescriptor desc) { 160 eventNames.remove(desc.getName()); 161 eventExtendedInfoDescriptors.remove(desc.getName()); 162 if (log.isDebugEnabled()) { 163 log.debug("Unregistered event: " + desc.getName()); 164 } 165 } 166 167 protected void doUnregisterExtendedInfo(ExtendedInfoDescriptor desc) { 168 // FIXME: this doesn't look right 169 extendedInfoDescriptors.remove(desc.getKey()); 170 if (log.isDebugEnabled()) { 171 log.debug("Unregistered extended info: " + desc.getKey()); 172 } 173 } 174 175 @Override 176 public <T> T getAdapter(Class<T> adapter) { 177 if (adapter.getCanonicalName().equals(DocumentHistoryReader.class.getCanonicalName())) { 178 return adapter.cast(new DocumentHistoryReaderImpl()); 179 } else { 180 if (backend != null) { 181 return adapter.cast(backend); 182 } else { 183 log.error("Can not provide service " + adapter.getCanonicalName() + " since backend is undefined"); 184 return null; 185 } 186 } 187 } 188 189 public Set<String> getAuditableEventNames() { 190 return eventNames; 191 } 192 193 public AuditBackend getBackend() { 194 return backend; 195 } 196 197 public Set<AdapterDescriptor> getDocumentAdapters() { 198 return documentAdapters; 199 } 200 201 /** 202 * @since 7.4 203 */ 204 public Map<String, List<ExtendedInfoDescriptor>> getEventExtendedInfoDescriptors() { 205 return eventExtendedInfoDescriptors; 206 } 207 208 public Set<ExtendedInfoDescriptor> getExtendedInfoDescriptors() { 209 return extendedInfoDescriptors; 210 } 211 212 @Override 213 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 214 if (extensionPoint.equals(EVENT_EXT_POINT)) { 215 doRegisterEvent((EventDescriptor) contribution); 216 } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { 217 doRegisterExtendedInfo((ExtendedInfoDescriptor) contribution); 218 } else if (extensionPoint.equals(ADAPTER_POINT)) { 219 doRegisterAdapter((AdapterDescriptor) contribution); 220 } else if (contribution instanceof AuditBackendDescriptor) { 221 backendConfig = (AuditBackendDescriptor)contribution; 222 } else if (contribution instanceof AuditBulkerDescriptor) { 223 bulkerConfig = (AuditBulkerDescriptor)contribution; 224 } 225 } 226 227 @Override 228 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 229 if (extensionPoint.equals(EVENT_EXT_POINT)) { 230 doUnregisterEvent((EventDescriptor) contribution); 231 } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { 232 doUnregisterExtendedInfo((ExtendedInfoDescriptor) contribution); 233 } else if (extensionPoint.equals(ADAPTER_POINT)) { 234 doUnregisterAdapter((AdapterDescriptor) contribution); 235 } 236 } 237 238}