/* * (C) Copyright 2006-2016 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: * Nuxeo - initial API and implementation * * $Id$ */ package org.nuxeo.ecm.platform.audit.service; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.platform.audit.api.DocumentHistoryReader; import org.nuxeo.ecm.platform.audit.api.document.DocumentHistoryReaderImpl; import org.nuxeo.ecm.platform.audit.service.extension.AdapterDescriptor; import org.nuxeo.ecm.platform.audit.service.extension.AuditBackendDescriptor; import org.nuxeo.ecm.platform.audit.service.extension.AuditBulkerDescriptor; import org.nuxeo.ecm.platform.audit.service.extension.EventDescriptor; import org.nuxeo.ecm.platform.audit.service.extension.ExtendedInfoDescriptor; import org.nuxeo.runtime.model.ComponentContext; import org.nuxeo.runtime.model.ComponentInstance; import org.nuxeo.runtime.model.ComponentName; import org.nuxeo.runtime.model.DefaultComponent; /** * Event service configuration. * * @author <a href="mailto:ja@nuxeo.com">Julien Anguenot</a> */ public class NXAuditEventsService extends DefaultComponent { public static final ComponentName NAME = new ComponentName( "org.nuxeo.ecm.platform.audit.service.NXAuditEventsService"); private static final String EVENT_EXT_POINT = "event"; private static final String EXTENDED_INFO_EXT_POINT = "extendedInfo"; private static final String ADAPTER_POINT = "adapter"; /** * If passed as true on the event properties, event not logged * * @since 5.7 */ public static final String DISABLE_AUDIT_LOGGER = "disableAuditLogger"; private static final String BACKEND_EXT_POINT = "backend"; protected static final Log log = LogFactory.getLog(NXAuditEventsService.class); protected final Set<ExtendedInfoDescriptor> extendedInfoDescriptors = new HashSet<ExtendedInfoDescriptor>(); protected final Map<String, List<ExtendedInfoDescriptor>> eventExtendedInfoDescriptors = new HashMap<String, List<ExtendedInfoDescriptor>>(); // the adapters that will injected in the EL context for extended // information protected final Set<AdapterDescriptor> documentAdapters = new HashSet<AdapterDescriptor>(); protected final Set<String> eventNames = new HashSet<String>(); protected AuditBackend backend; protected AuditBackendDescriptor backendConfig = new AuditBackendDescriptor(); protected AuditBulker bulker; protected AuditBulkerDescriptor bulkerConfig = new AuditBulkerDescriptor(); @Override public int getApplicationStartedOrder() { return backendConfig.getApplicationStartedOrder(); } @Override public void applicationStarted(ComponentContext context) { backend = backendConfig.newInstance(this); backend.onApplicationStarted(); bulker = bulkerConfig.newInstance(backend); bulker.onApplicationStarted(); } @Override public void applicationStopped(ComponentContext context, Instant deadline) { try { bulker.onApplicationStopped(); } finally { backend.onApplicationStopped(); } } protected void doRegisterAdapter(AdapterDescriptor desc) { if (log.isDebugEnabled()) { log.debug("Registered adapter : " + desc.getName()); } documentAdapters.add(desc); } protected void doRegisterEvent(EventDescriptor desc) { String eventName = desc.getName(); boolean eventEnabled = desc.getEnabled(); if (eventEnabled) { eventNames.add(eventName); if (log.isDebugEnabled()) { log.debug("Registered event: " + eventName); } for (ExtendedInfoDescriptor extInfoDesc : desc.getExtendedInfoDescriptors()) { if (extInfoDesc.getEnabled()) { if (eventExtendedInfoDescriptors.containsKey(eventName)) { eventExtendedInfoDescriptors.get(eventName).add(extInfoDesc); } else { List<ExtendedInfoDescriptor> toBeAdded = new ArrayList<ExtendedInfoDescriptor>(); toBeAdded.add(extInfoDesc); eventExtendedInfoDescriptors.put(eventName, toBeAdded); } } else { if (eventExtendedInfoDescriptors.containsKey(eventName)) { eventExtendedInfoDescriptors.get(eventName).remove(extInfoDesc); } } } } else if (eventNames.contains(eventName) && !eventEnabled) { doUnregisterEvent(desc); } } protected void doRegisterExtendedInfo(ExtendedInfoDescriptor desc) { if (log.isDebugEnabled()) { log.debug("Registered extended info mapping : " + desc.getKey()); } extendedInfoDescriptors.add(desc); } protected void doUnregisterAdapter(AdapterDescriptor desc) { // FIXME: this doesn't look right documentAdapters.remove(desc.getName()); if (log.isDebugEnabled()) { log.debug("Unregistered adapter: " + desc.getName()); } } protected void doUnregisterEvent(EventDescriptor desc) { eventNames.remove(desc.getName()); eventExtendedInfoDescriptors.remove(desc.getName()); if (log.isDebugEnabled()) { log.debug("Unregistered event: " + desc.getName()); } } protected void doUnregisterExtendedInfo(ExtendedInfoDescriptor desc) { // FIXME: this doesn't look right extendedInfoDescriptors.remove(desc.getKey()); if (log.isDebugEnabled()) { log.debug("Unregistered extended info: " + desc.getKey()); } } @Override public <T> T getAdapter(Class<T> adapter) { if (adapter.getCanonicalName().equals(DocumentHistoryReader.class.getCanonicalName())) { return adapter.cast(new DocumentHistoryReaderImpl()); } else { if (backend != null) { return adapter.cast(backend); } else { log.error("Can not provide service " + adapter.getCanonicalName() + " since backend is undefined"); return null; } } } public Set<String> getAuditableEventNames() { return eventNames; } public AuditBackend getBackend() { return backend; } public Set<AdapterDescriptor> getDocumentAdapters() { return documentAdapters; } /** * @since 7.4 */ public Map<String, List<ExtendedInfoDescriptor>> getEventExtendedInfoDescriptors() { return eventExtendedInfoDescriptors; } public Set<ExtendedInfoDescriptor> getExtendedInfoDescriptors() { return extendedInfoDescriptors; } @Override public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { if (extensionPoint.equals(EVENT_EXT_POINT)) { doRegisterEvent((EventDescriptor) contribution); } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { doRegisterExtendedInfo((ExtendedInfoDescriptor) contribution); } else if (extensionPoint.equals(ADAPTER_POINT)) { doRegisterAdapter((AdapterDescriptor) contribution); } else if (contribution instanceof AuditBackendDescriptor) { backendConfig = (AuditBackendDescriptor)contribution; } else if (contribution instanceof AuditBulkerDescriptor) { bulkerConfig = (AuditBulkerDescriptor)contribution; } } @Override public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { if (extensionPoint.equals(EVENT_EXT_POINT)) { doUnregisterEvent((EventDescriptor) contribution); } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { doUnregisterExtendedInfo((ExtendedInfoDescriptor) contribution); } else if (extensionPoint.equals(ADAPTER_POINT)) { doUnregisterAdapter((AdapterDescriptor) contribution); } } }