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 *     Bogdan Stefanescu
018 *     Florent Guillaume
019 */
020package org.nuxeo.ecm.core.event;
021
022import java.time.Duration;
023
024import org.nuxeo.ecm.core.event.impl.EventListenerDescriptor;
025import org.nuxeo.ecm.core.event.impl.EventServiceImpl;
026import org.nuxeo.ecm.core.event.pipe.EventPipeDescriptor;
027import org.nuxeo.ecm.core.event.pipe.dispatch.EventDispatcherDescriptor;
028import org.nuxeo.runtime.RuntimeMessage.Level;
029import org.nuxeo.runtime.RuntimeMessage.Source;
030import org.nuxeo.ecm.core.event.stream.DomainEventProducerDescriptor;
031import org.nuxeo.runtime.api.Framework;
032import org.nuxeo.runtime.model.ComponentContext;
033import org.nuxeo.runtime.model.ComponentInstance;
034import org.nuxeo.runtime.model.ComponentName;
035import org.nuxeo.runtime.model.DefaultComponent;
036
037/**
038 * Event Service Component, allowing registration of contributions and doing the event service shutdown upon
039 * deactivation.
040 */
041public class EventServiceComponent extends DefaultComponent {
042
043    public static final int APPLICATION_STARTED_ORDER = -500;
044
045    public static final String EVENT_LISTENER_XP = "listener";
046
047    public static final String EVENT_PIPE_XP = "pipe";
048
049    public static final String EVENT_DISPATCHER_XP = "dispatcher";
050
051    // @since 11.4
052    public static final String DOMAIN_EVENT_PRODUCER_XP = "domainEventProducer";
053
054    public static final long DEFAULT_SHUTDOWN_TIMEOUT = Duration.ofSeconds(5).toMillis();
055
056    protected EventServiceImpl service;
057
058    @Override
059    public void activate(ComponentContext context) {
060        service = new EventServiceImpl();
061    }
062
063    @Override
064    public void applicationStarted(ComponentContext context) {
065        service.init();
066    }
067
068    @Override
069    public void deactivate(ComponentContext context) {
070        if (service != null) {
071            String s = Framework.getProperty("org.nuxeo.ecm.core.event.shutdown.timeoutMillis");
072            long timeout = s == null ? DEFAULT_SHUTDOWN_TIMEOUT : Long.parseLong(s);
073            try {
074                service.shutdown(timeout);
075            } catch (InterruptedException e) {
076                Thread.currentThread().interrupt();
077                throw new RuntimeException(e);
078            }
079            service = null;
080        }
081    }
082
083    @Override
084    public int getApplicationStartedOrder() {
085        return APPLICATION_STARTED_ORDER;
086    }
087
088    @Override
089    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
090        if (EVENT_LISTENER_XP.equals(extensionPoint)) {
091            EventListenerDescriptor descriptor = (EventListenerDescriptor) contribution;
092            descriptor.setRuntimeContext(contributor.getRuntimeContext());
093            try {
094                service.addEventListener(descriptor);
095            } catch (RuntimeException e) {
096                ComponentName compName = contributor.getName();
097                String msg = "Failed to register event listener in component '" + compName
098                        + "': error initializing event listener '" + descriptor.getName() + "' (" + e.toString() + ')';
099                addRuntimeMessage(Level.ERROR, msg, Source.EXTENSION, compName.getName());
100            }
101        } else if (EVENT_PIPE_XP.equals(extensionPoint)) {
102            EventPipeDescriptor descriptor = (EventPipeDescriptor) contribution;
103            service.addEventPipe(descriptor);
104        } else if (EVENT_DISPATCHER_XP.equals(extensionPoint)) {
105            EventDispatcherDescriptor descriptor = (EventDispatcherDescriptor) contribution;
106            service.addEventDispatcher(descriptor);
107        } else if (DOMAIN_EVENT_PRODUCER_XP.equals(extensionPoint)) {
108            DomainEventProducerDescriptor descriptor = (DomainEventProducerDescriptor) contribution;
109            service.addDomainEventProducer(descriptor);
110        }
111    }
112
113    @Override
114    public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
115        if (EVENT_LISTENER_XP.equals(extensionPoint)) {
116            service.removeEventListener((EventListenerDescriptor) contribution);
117        } else if (EVENT_PIPE_XP.equals(extensionPoint)) {
118            EventPipeDescriptor descriptor = (EventPipeDescriptor) contribution;
119            service.removeEventPipe(descriptor);
120        } else if (EVENT_DISPATCHER_XP.equals(extensionPoint)) {
121            EventDispatcherDescriptor descriptor = (EventDispatcherDescriptor) contribution;
122            service.removeEventDispatcher(descriptor);
123        } else if (DOMAIN_EVENT_PRODUCER_XP.equals(extensionPoint)) {
124            DomainEventProducerDescriptor descriptor = (DomainEventProducerDescriptor) contribution;
125            service.removeDomainEventProducer(descriptor);
126        }
127    }
128
129    @SuppressWarnings("unchecked")
130    @Override
131    public <T> T getAdapter(Class<T> adapter) {
132        if (EventService.class == adapter || EventProducer.class == adapter || EventServiceAdmin.class == adapter) {
133            return (T) service;
134        }
135        return null;
136    }
137
138}