/******************************************************************************* * * Copyright 2012-2015, the original author or authors. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obta 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.flipkart.aesop.eventconsumer.implementation; import com.flipkart.aesop.destinationoperation.implementation.DefaultDeleteDataLayer; import com.flipkart.aesop.destinationoperation.implementation.DefaultUpsertDataLayer; import com.flipkart.aesop.event.AbstractEvent; import com.flipkart.aesop.event.EventFactory; import com.flipkart.aesop.eventconsumer.AbstractEventConsumer; import com.flipkart.aesop.mapper.Mapper; import com.flipkart.aesop.mapper.implementation.DefaultMapperImpl; import com.flipkart.aesop.processor.DestinationEventProcessor; import com.flipkart.aesop.transformer.PostMappingTransformer; import com.flipkart.aesop.transformer.PreMappingTransformer; import com.linkedin.databus.client.pub.ConsumerCallbackResult; import com.linkedin.databus.client.pub.DbusEventDecoder; import com.linkedin.databus.core.DbusEvent; import com.linkedin.databus.core.DbusOpcode; import com.linkedin.databus2.core.DatabusException; import javax.naming.OperationNotSupportedException; import java.util.List; import java.util.Map; /** * Default Implementation of {@link AbstractEventConsumer}. * Different {@link Mapper}, {@link DestinationEventProcessor} can be implemented and plugged in. Though, default * implementations are provided. * <p> * @author Prakhar Jain * @see DefaultMapperImpl * @see DefaultUpsertDataLayer * @see DefaultDeleteDataLayer */ public class DefaultEventConsumerImpl extends AbstractEventConsumer { /* PreMappingTransformer instance for pre mapping transformation */ private PreMappingTransformer preMappingTransformer; /* PreMappingTransformer instance for post mapping transformation */ private PostMappingTransformer postMappingTransformer; /** Object Builder for this class. */ public static class Builder extends AbstractEventConsumer.Builder<DefaultEventConsumerImpl> { private PreMappingTransformer preMappingTransformer; private PostMappingTransformer postMappingTransformer; public Builder(EventFactory sourceEventFactory, Mapper mapper, Map<DbusOpcode, ? extends DestinationEventProcessor> destinationEventProcessorMap) { super(sourceEventFactory, mapper, destinationEventProcessorMap); } public PreMappingTransformer getPreMappingTransformer() { return preMappingTransformer; } public PostMappingTransformer getPostMappingTransformer() { return postMappingTransformer; } public Builder withPreMappingTransformer(PreMappingTransformer preMappingTransformer) { this.preMappingTransformer = preMappingTransformer; return this; } public Builder withPostMappingTransformer(PostMappingTransformer postMappingTransformer) { this.postMappingTransformer = postMappingTransformer; return this; } @Override public DefaultEventConsumerImpl build() { return new DefaultEventConsumerImpl(this); } } /** * Private Constructor that uses {@link Builder} instance. * @param builder : Builder object to build EventConsumer */ private DefaultEventConsumerImpl(Builder builder) { this.mapper = builder.getMapper(); this.sourceEventFactory = builder.getSourceEventFactory(); this.destinationGroupSet = builder.getDestinationGroupSet(); this.destinationProcessorMap = builder.getDestinationProcessorMap(); this.totalDestinationGroups = builder.getTotalDestinationGroups(); this.preMappingTransformer = builder.getPreMappingTransformer(); this.postMappingTransformer = builder.getPostMappingTransformer(); } @Override public AbstractEvent decodeSourceEvent(DbusEvent dbusEvent, DbusEventDecoder eventDecoder) throws DatabusException { return sourceEventFactory.createEvent(dbusEvent, eventDecoder); } @Override public ConsumerCallbackResult processSourceEvent(AbstractEvent sourceEvent) { /* Pre Mapping of Source Event , calling PreMappingTransformer for the source event */ AbstractEvent sourceEventAfterTransformation = preMappingTransformer == null ? sourceEvent : preMappingTransformer.transform(sourceEvent); List<AbstractEvent> destinationEventList = mapper.mapSourceEventToDestinationEvent(sourceEventAfterTransformation, destinationGroupSet, totalDestinationGroups); for (AbstractEvent destinationEvent : destinationEventList) { /* Post Mapping of Source Event , calling PreMappingTransformer for the destination event */ AbstractEvent destinationEventAfterTransformation = (postMappingTransformer == null ? destinationEvent : postMappingTransformer.transform(destinationEvent)); DestinationEventProcessor destinationEventProcessor = destinationProcessorMap.get(destinationEvent.getEventType()); /* Process Destination Events */ try { if (destinationEventProcessor != null) { ConsumerCallbackResult result = destinationEventProcessor .processDestinationEvent(destinationEventAfterTransformation); if (ConsumerCallbackResult.isFailure(result)) { return result; } } } catch (OperationNotSupportedException e) { LOGGER.error("Operation Not Supported Exception occured while executing Destination Store Operation.", e); return ConsumerCallbackResult.ERROR; } } return ConsumerCallbackResult.SUCCESS; } }