Java tutorial
/* * Copyright 2014 Informatica Corp. * * 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. */ package com.informatica.surf; import com.informatica.um.binge.api.impl.VDSEventImpl; import com.informatica.um.binge.api.impl.VDSEventListImpl; import com.informatica.um.binge.api.impl.VDSEventListPoolFactory; import com.informatica.um.binge.api.impl.VDSEventPoolFactory; import com.informatica.um.binge.api.impl.VDSMessageAckSource; import com.informatica.vds.api.*; import com.lmax.disruptor.EventHandler; import com.lmax.disruptor.RingBuffer; import com.lmax.disruptor.dsl.Disruptor; import org.apache.commons.pool.impl.GenericKeyedObjectPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.Executors; /** * * @author jraj */ public class Node implements Runnable, EventHandler<SurfEvent> { private final VDSSource _source; private final VDSTarget _target; private final Map<Object, VDSConfiguration> _context; private static final Logger _logger = LoggerFactory.getLogger(Node.class); private volatile boolean _shutdown = false; private final VDSMessageAckSource _acksource; private final boolean _needsAck; private final GenericKeyedObjectPool<Integer, VDSEventListImpl> _eventListPool; private final List<VDSTransform> _transforms; public Node(VDSSource source, VDSTarget target, List<VDSTransform> transforms, Map<Object, VDSConfiguration> ctx) { _logger.info("Creating node..."); _source = source; _target = target; _transforms = transforms; _context = ctx; if (source instanceof VDSMessageAckSource) { _acksource = (VDSMessageAckSource) source; _needsAck = true; } else { _acksource = null; _needsAck = false; } GenericKeyedObjectPool<Integer, VDSEventImpl> evtpool = new GenericKeyedObjectPool( new VDSEventPoolFactory()); evtpool.setMaxActive(-1); evtpool.setMaxTotal(10000); _eventListPool = new GenericKeyedObjectPool<>(new VDSEventListPoolFactory(evtpool)); _eventListPool.setMaxActive(-1); _eventListPool.setMaxTotal(10000); } public void open() throws Exception { _logger.info("Opening source and target connections..."); _source.open(_context.get(_source)); _target.open(_context.get(_target)); _logger.info("Initializing transforms"); for (VDSTransform tx : _transforms) { tx.open(_context.get(tx)); } } @Override public void run() { _logger.info("Node run starting..."); Executor executor = Executors.newCachedThreadPool(); Disruptor<SurfEvent> disruptor = new Disruptor<>(SurfEvent.EVENT_FACTORY, 128, executor); disruptor.handleEventsWith(this); RingBuffer<SurfEvent> buffer = disruptor.start(); VDSEventListImpl events = null; while (!_shutdown) { try { events = _eventListPool.borrowObject(0); while (events.getEventsList().isEmpty()) { _source.read(events); } if (_needsAck) { Object obj = _acksource.getInputObject(); // Hacking this in for now // Need to actually ack the object after Kinesis consumes it: TODO _acksource.updateInputObject(obj); } long seq = buffer.next(); SurfEvent event = buffer.get(seq); event.setEventlist(events); buffer.publish(seq); } catch (Exception ex) { _logger.error("Exception while reading data:", ex); ex.printStackTrace(); } } } public void shutdown() { _shutdown = true; } @Override public void onEvent(SurfEvent surfEvent, long l, boolean b) throws Exception { VDSEventListImpl srcEvents = surfEvent.getEventlist(); VDSEventListImpl txEvents = null; try { txEvents = applyTransforms(srcEvents, _transforms.iterator()); } catch (Exception ex) { _logger.warn("Exception while invoking transforms. Skipping event.", ex); return; } try { _logger.debug("Sending events to target..."); for (VDSEventImpl evt : txEvents.getEventsList()) { _target.write(evt); } } catch (Exception ex) { _logger.warn("Exception while handling event", ex); } finally { _eventListPool.returnObject(0, txEvents); } } private VDSEventListImpl applyTransforms(VDSEventListImpl srcEvents, Iterator<VDSTransform> transforms) throws Exception { if (!transforms.hasNext()) { return srcEvents; } VDSTransform tx = transforms.next(); VDSEventListImpl outlist = _eventListPool.borrowObject(0); for (VDSEventImpl evt : srcEvents.getEventsList()) { tx.apply(evt, outlist); } _eventListPool.returnObject(0, srcEvents); return applyTransforms(outlist, transforms); } }