/* * Copyright (c) 2016, 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.receiver.core.internal.management; import org.apache.log4j.Logger; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.databridge.commons.Event; import org.wso2.carbon.databridge.commons.StreamDefinition; import org.wso2.carbon.event.processor.manager.core.EventManagementUtil; import org.wso2.carbon.event.processor.manager.core.EventSync; import org.wso2.carbon.event.processor.manager.core.Manager; import org.wso2.carbon.event.receiver.core.internal.ds.EventReceiverServiceValueHolder; import org.wso2.siddhi.core.util.snapshot.ByteSerializer; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class QueueInputEventDispatcher extends AbstractInputEventDispatcher implements EventSync { private final StreamDefinition streamDefinition; private Logger log = Logger.getLogger(AbstractInputEventDispatcher.class); private final BlockingEventQueue eventQueue; private Lock readLock; private String syncId; private int tenantId; private ReentrantLock threadBarrier = new ReentrantLock(); private ExecutorService executorService = Executors.newSingleThreadExecutor(); private boolean isContinue = false; private String originalEventStreamId; public QueueInputEventDispatcher(int tenantId, String syncId, Lock readLock, StreamDefinition exportedStreamDefinition, int eventQueueSizeMb, int eventSyncQueueSize) { this.readLock = readLock; this.tenantId = tenantId; this.syncId = syncId; this.eventQueue = new BlockingEventQueue(eventQueueSizeMb, eventSyncQueueSize); this.originalEventStreamId = exportedStreamDefinition.getStreamId(); this.streamDefinition = EventManagementUtil.constructDatabridgeStreamDefinition(syncId, exportedStreamDefinition); this.executorService.submit(new QueueInputEventDispatcherWorker()); } @Override public void onEvent(Event event) { try { threadBarrier.lock(); eventQueue.put(event); threadBarrier.unlock(); } catch (InterruptedException e) { log.error("Interrupted while waiting to put the event to queue.", e); } } @Override public void shutdown() { executorService.shutdown(); } @Override public byte[] getState() { threadBarrier.lock(); byte[] state = ByteSerializer.OToB(eventQueue); threadBarrier.unlock(); return state; } @Override public void syncState(byte[] bytes) { BlockingEventQueue events = (BlockingEventQueue) ByteSerializer.BToO(bytes); while (events.peek() != null) { if (events.poll().equals(eventQueue.peek())) { eventQueue.poll(); } else { break; } } } @Override public void process(Event event) { if(isContinueProcess()){ readLock.lock(); readLock.unlock(); callBack.sendEvent(event); } } @Override public StreamDefinition getStreamDefinition() { return streamDefinition; } @Override public boolean isContinueProcess() { return isContinue; } @Override public void setContinueProcess(boolean isContinue) { this.isContinue = isContinue; } @Override public String getOriginalEventStreamId() { return originalEventStreamId; } class QueueInputEventDispatcherWorker implements Runnable { @Override public void run() { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId); PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true); while (true) { try { readLock.lock(); readLock.unlock(); Event event = eventQueue.take(); readLock.lock(); readLock.unlock(); if(isContinueProcess()){ callBack.sendEvent(event); } if (isSendToOther()) { EventReceiverServiceValueHolder.getEventManagementService().syncEvent(syncId, Manager.ManagerType.Receiver, event); } } catch (InterruptedException e) { log.error("Interrupted while waiting to get an event from queue.", e); } } } catch (Exception e) { log.error("Error in dispatching events:" + e.getMessage(), e); } finally { PrivilegedCarbonContext.endTenantFlow(); } } } }