/* * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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. */ package org.wso2.carbon.event.processor.manager.core.internal; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import com.hazelcast.core.MemberAttributeEvent; import com.hazelcast.core.MembershipEvent; import com.hazelcast.core.MembershipListener; import org.apache.log4j.Logger; import org.wso2.carbon.databridge.commons.Event; import org.wso2.carbon.event.processor.manager.core.EventManagementService; import org.wso2.carbon.event.processor.manager.core.EventProcessorManagementService; import org.wso2.carbon.event.processor.manager.core.EventPublisherManagementService; import org.wso2.carbon.event.processor.manager.core.EventReceiverManagementService; import org.wso2.carbon.event.processor.manager.core.EventSync; import org.wso2.carbon.event.processor.manager.core.Manager; import org.wso2.carbon.event.processor.manager.core.config.DistributedConfiguration; import org.wso2.carbon.event.processor.manager.core.config.HAConfiguration; import org.wso2.carbon.event.processor.manager.core.config.ManagementModeInfo; import org.wso2.carbon.event.processor.manager.core.config.Mode; import org.wso2.carbon.event.processor.manager.core.config.PersistenceConfiguration; import org.wso2.carbon.event.processor.manager.core.exception.EventManagementException; import org.wso2.carbon.event.processor.manager.core.exception.ManagementConfigurationException; import org.wso2.carbon.event.processor.manager.core.internal.ds.EventManagementServiceValueHolder; import org.wso2.carbon.event.processor.manager.core.internal.util.ConfigurationConstants; import org.wso2.carbon.event.processor.manager.core.internal.util.ManagementModeConfigurationLoader; import org.wso2.carbon.utils.ConfigurationContextService; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class CarbonEventManagementService implements EventManagementService { private static Logger log = Logger.getLogger(CarbonEventManagementService.class); private Mode mode = Mode.SingleNode; private ManagementModeInfo managementModeInfo; private EventProcessorManagementService processorManager; private EventReceiverManagementService receiverManager; private List<EventPublisherManagementService> publisherManager; private EventHandler receiverEventHandler = new EventHandler(); private EventHandler presenterEventHandler = new EventHandler(); private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(3); private HAManager haManager = null; private IMap<String, Long> haEventPublisherTimeSyncMap = null; private PersistenceManager persistenceManager = null; private StormReceiverCoordinator stormReceiverCoordinator = null; private boolean isManagerNode = false; private boolean isWorkerNode = false; private boolean isPresenterNode = false; public CarbonEventManagementService() { try { managementModeInfo = ManagementModeConfigurationLoader.loadManagementModeInfo(); mode = managementModeInfo.getMode(); publisherManager = new CopyOnWriteArrayList<>(); } catch (ManagementConfigurationException e) { throw new EventManagementException("Error getting management mode information", e); } if (mode == Mode.HA) { // HA Configuration. HAConfiguration haConfiguration = managementModeInfo.getHaConfiguration(); isWorkerNode = haConfiguration.isWorkerNode(); isPresenterNode = haConfiguration.isPresenterNode(); if (isWorkerNode) { // Persistence Configuration. PersistenceConfiguration persistConfig = managementModeInfo.getPersistenceConfiguration(); if (persistConfig != null) { ScheduledExecutorService scheduledExecutorService = Executors .newScheduledThreadPool(persistConfig.getThreadPoolSize()); long persistenceTimeInterval = persistConfig.getPersistenceTimeInterval(); if (persistenceTimeInterval > 0) { persistenceManager = new PersistenceManager(scheduledExecutorService, persistenceTimeInterval); } } receiverEventHandler.startServer(haConfiguration.getEventSyncConfig()); } if (isPresenterNode && !isWorkerNode) { presenterEventHandler.startServer(haConfiguration.getLocalPresenterConfig()); } } else if (mode == Mode.SingleNode) { PersistenceConfiguration persistConfig = managementModeInfo.getPersistenceConfiguration(); if (persistConfig != null) { ScheduledExecutorService scheduledExecutorService = Executors .newScheduledThreadPool(persistConfig.getThreadPoolSize()); long persistenceTimeInterval = persistConfig.getPersistenceTimeInterval(); if (persistenceTimeInterval > 0) { persistenceManager = new PersistenceManager(scheduledExecutorService, persistenceTimeInterval); persistenceManager.init(); } } } else if (mode == Mode.Distributed) { DistributedConfiguration distributedConfiguration = managementModeInfo.getDistributedConfiguration(); isManagerNode = distributedConfiguration.isManagerNode(); isWorkerNode = distributedConfiguration.isWorkerNode(); if (isWorkerNode) { stormReceiverCoordinator = new StormReceiverCoordinator(); } isPresenterNode = distributedConfiguration.isPresenterNode(); if (isPresenterNode) { presenterEventHandler.startServer(distributedConfiguration.getLocalPresenterConfig()); } } } public void init(HazelcastInstance hazelcastInstance) { if (mode == Mode.HA) { HAConfiguration haConfiguration = managementModeInfo.getHaConfiguration(); if (isWorkerNode) { receiverEventHandler.init(ConfigurationConstants.RECEIVERS, haConfiguration.getEventSyncConfig(), haConfiguration.constructEventSyncPublisherConfig(), isWorkerNode); haManager = new HAManager(hazelcastInstance, haConfiguration, executorService, receiverEventHandler, presenterEventHandler); haManager.init(); if (haEventPublisherTimeSyncMap == null) { haEventPublisherTimeSyncMap = EventManagementServiceValueHolder.getHazelcastInstance().getMap(ConfigurationConstants.HA_EVENT_PUBLISHER_TIME_SYNC_MAP); } } presenterEventHandler.init(ConfigurationConstants.PRESENTERS, haConfiguration.getLocalPresenterConfig(), haConfiguration.constructPresenterPublisherConfig(), isPresenterNode && !isWorkerNode); checkMemberUpdate(); } else if (mode == Mode.Distributed) { if (stormReceiverCoordinator != null) { stormReceiverCoordinator.tryBecomeCoordinator(); } DistributedConfiguration distributedConfiguration = managementModeInfo.getDistributedConfiguration(); presenterEventHandler.init(ConfigurationConstants.PRESENTERS, distributedConfiguration .getLocalPresenterConfig(), distributedConfiguration.constructPresenterPublisherConfig(), isPresenterNode); checkMemberUpdate(); } else if (mode == Mode.SingleNode) { log.warn("CEP started with clustering enabled, but SingleNode configuration given."); } hazelcastInstance.getCluster().addMembershipListener(new MembershipListener() { @Override public void memberAdded(MembershipEvent membershipEvent) { presenterEventHandler.registerLocalMember(); receiverEventHandler.registerLocalMember(); checkMemberUpdate(); if (mode == Mode.HA) { if (isWorkerNode && haManager != null) { haManager.verifyState(); } } } @Override public void memberRemoved(MembershipEvent membershipEvent) { receiverEventHandler.removeMember(membershipEvent.getMember().getUuid()); presenterEventHandler.removeMember(membershipEvent.getMember().getUuid()); checkMemberUpdate(); if (mode == Mode.HA) { if (isWorkerNode && haManager != null) { haManager.tryChangeState(); } } else if (mode == Mode.Distributed) { if (stormReceiverCoordinator != null) { stormReceiverCoordinator.tryBecomeCoordinator(); } } } @Override public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) { } }); } public void init(ConfigurationContextService configurationContextService) { if (mode == Mode.SingleNode || isWorkerNode) { receiverManager.start(); } if ((mode == Mode.Distributed || mode == Mode.HA) && isWorkerNode || mode == Mode.SingleNode) { executorService.schedule(new Runnable() { @Override public void run() { try { log.info("Starting polling event receivers"); EventReceiverManagementService eventReceiverManagementService = getEventReceiverManagementService(); if (eventReceiverManagementService != null) { eventReceiverManagementService.startPolling(); } else { log.error("Adapter polling failed as EventReceiverManagementService not available"); } } catch (Exception e) { log.error("Unexpected error occurred when start polling event adapters", e); } } }, ConfigurationConstants.AXIS_TIME_INTERVAL_IN_MILLISECONDS * 4, TimeUnit.MILLISECONDS); } int checkMemberUpdateInterval = 10 * 1000; if (mode == Mode.Distributed) { DistributedConfiguration distributedConfiguration = managementModeInfo.getDistributedConfiguration(); checkMemberUpdateInterval = distributedConfiguration.getMemberUpdateCheckInterval(); } else if (mode == Mode.HA) { HAConfiguration haConfiguration = managementModeInfo.getHaConfiguration(); checkMemberUpdateInterval = haConfiguration.getCheckMemberUpdateInterval(); } if (mode == Mode.Distributed || mode == Mode.HA) { executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { checkMemberUpdate(); } }, checkMemberUpdateInterval, checkMemberUpdateInterval, TimeUnit.MILLISECONDS); } } public void shutdown() { if (haManager != null) { haManager.shutdown(); } if (executorService != null) { executorService.shutdown(); } if (persistenceManager != null) { persistenceManager.shutdown(); } receiverEventHandler.shutdown(); presenterEventHandler.shutdown(); } public byte[] getState() { if (mode == Mode.HA) { if (isWorkerNode) { return haManager.getState(); } } return null; } public ManagementModeInfo getManagementModeInfo() { return managementModeInfo; } public void subscribe(Manager manager) { if (manager.getType() == Manager.ManagerType.Processor) { this.processorManager = (EventProcessorManagementService) manager; } else if (manager.getType() == Manager.ManagerType.Receiver) { this.receiverManager = (EventReceiverManagementService) manager; } else if (manager.getType() == Manager.ManagerType.Publisher) { this.publisherManager.add((EventPublisherManagementService) manager); } } @Override public void unsubscribe(Manager manager) { if (manager.getType() == Manager.ManagerType.Processor) { this.processorManager = null; } else if (manager.getType() == Manager.ManagerType.Receiver) { this.receiverManager = null; } else if (manager.getType() == Manager.ManagerType.Publisher) { this.publisherManager.remove(manager); } } @Override public void syncEvent(String syncId, Manager.ManagerType type, Event event) { if (type == Manager.ManagerType.Receiver) { receiverEventHandler.syncEvent(syncId, event); } else { presenterEventHandler.syncEvent(syncId, event); } } @Override public void registerEventSync(EventSync eventSync, Manager.ManagerType type) { if (type == Manager.ManagerType.Receiver) { receiverEventHandler.registerEventSync(eventSync); } else { presenterEventHandler.registerEventSync(eventSync); } } @Override public void unregisterEventSync(String syncId, Manager.ManagerType type) { if (type == Manager.ManagerType.Receiver) { receiverEventHandler.unregisterEventSync(syncId); } else { presenterEventHandler.unregisterEventSync(syncId); } } public EventProcessorManagementService getEventProcessorManagementService() { return processorManager; } public EventReceiverManagementService getEventReceiverManagementService() { return receiverManager; } public List<EventPublisherManagementService> getEventPublisherManagementService() { return publisherManager; } private void checkMemberUpdate() { if (isWorkerNode) { if (mode == Mode.HA) { receiverEventHandler.checkMemberUpdate(); presenterEventHandler.checkMemberUpdate(); } else if (mode == Mode.Distributed) { presenterEventHandler.checkMemberUpdate(); } } } @Override public void updateLatestEventSentTime(String publisherName, int tenantId, long timestamp) { haEventPublisherTimeSyncMap.putAsync(tenantId + "-" + publisherName, EventManagementServiceValueHolder.getHazelcastInstance().getCluster().getClusterTime()); } @Override public long getLatestEventSentTime(String publisherName, int tenantId) { if (haEventPublisherTimeSyncMap == null) { haEventPublisherTimeSyncMap = EventManagementServiceValueHolder.getHazelcastInstance() .getMap(ConfigurationConstants.HA_EVENT_PUBLISHER_TIME_SYNC_MAP); } Long latestTimePublished = haEventPublisherTimeSyncMap.get(tenantId + "-" + publisherName); if (latestTimePublished != null) { return latestTimePublished; } return 0; } @Override public long getClusterTimeInMillis() { return EventManagementServiceValueHolder.getHazelcastInstance().getCluster().getClusterTime(); } public void initPersistence() { if (persistenceManager != null) { persistenceManager.init(); } } public void stopPersistence() { if (persistenceManager != null) { persistenceManager.shutdown(); } } }