/** * Copyright 2014 Comcast Cable Communications Management, LLC * * 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.comcast.viper.flume2storm.sink; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationConverter; import org.apache.commons.configuration.MapConfiguration; import com.comcast.viper.flume2storm.F2SConfigurationException; import com.comcast.viper.flume2storm.connection.parameters.ConnectionParametersFactory; import com.comcast.viper.flume2storm.connection.sender.EventSenderFactory; import com.comcast.viper.flume2storm.location.LocationServiceFactory; import com.comcast.viper.flume2storm.location.ServiceProviderSerialization; import com.google.common.base.Preconditions; import com.google.common.base.Supplier; /** * Configuration for {@link StormSink} */ public class StormSinkConfiguration implements Supplier<Configuration> { /** Configuration attribute name for {@link #getBatchSize()} */ public static final String BATCH_SIZE = "batch-size"; /** Default value for {@value #BATCH_SIZE} */ public static final int BATCH_SIZE_DEFAULT = 100; /** * Configuration attribute name for * {@link #getLocationServiceFactoryClassName()} */ public static final String LOCATION_SERVICE_FACTORY_CLASS = "location.service.factory"; /** Default value for {@value #LOCATION_SERVICE_FACTORY_CLASS} */ public static final String LOCATION_SERVICE_FACTORY_CLASS_DEFAULT = "com.comcast.viper.flume2storm.location.DynamicLocationServiceFactory"; /** * Configuration attribute name for * {@link #getServiceProviderSerializationClassName()} */ public static final String SERVICE_PROVIDER_SERIALIZATION_CLASS = "service.provider.serialization"; /** Default value for {@value #SERVICE_PROVIDER_SERIALIZATION_CLASS} */ public static final String SERVICE_PROVIDER_SERIALIZATION_CLASS_DEFAULT = "com.comcast.viper.flume2storm.location.KryoNetServiceProviderSerialization"; /** Configuration attribute name for {@link #getEventSenderFactoryClassName()} */ public static final String EVENT_SENDER_FACTORY_CLASS = "event.sender.factory"; /** Default value for {@value #EVENT_SENDER_FACTORY_CLASS} */ public static final String EVENT_SENDER_FACTORY_CLASS_DEFAULT = "com.comcast.viper.flume2storm.connection.sender.KryoNetEventSenderFactory"; /** * Configuration attribute name for * {@link #getConnectionParametersFactoryClassName()} */ public static final String CONNECTION_PARAMETERS_FACTORY_CLASS = "connection.parameters.factory"; /** Default value for {@value #CONNECTION_PARAMETERS_FACTORY_CLASS} */ public static final String CONNECTION_PARAMETERS_FACTORY_CLASS_DEFAULT = "com.comcast.viper.flume2storm.connection.parameters.KryoNetConnectionParametersFactory"; protected int batchSize; protected String locationServiceFactoryClassName; protected String serviceProviderSerializationClassName; protected String eventSenderFactoryClassName; protected String connectionParametersFactoryClassName; protected Configuration configuration; /** * @param config * The configuration to use * @return The newly built {@link StormSinkConfiguration} based on the * configuration specified * @throws F2SConfigurationException * If the configuration is invalid */ public static StormSinkConfiguration from(Configuration config) throws F2SConfigurationException { StormSinkConfiguration result = new StormSinkConfiguration(); try { result.setBatchSize(config.getInteger(BATCH_SIZE, BATCH_SIZE_DEFAULT)); } catch (Exception e) { throw F2SConfigurationException.with(config, BATCH_SIZE, e); } try { result.setLocationServiceFactoryClassName(config.getString(LOCATION_SERVICE_FACTORY_CLASS, LOCATION_SERVICE_FACTORY_CLASS_DEFAULT)); } catch (Exception e) { throw F2SConfigurationException.with(config, LOCATION_SERVICE_FACTORY_CLASS, e); } try { result.setServiceProviderSerializationClassName(config.getString(SERVICE_PROVIDER_SERIALIZATION_CLASS, SERVICE_PROVIDER_SERIALIZATION_CLASS_DEFAULT)); } catch (Exception e) { throw F2SConfigurationException.with(config, SERVICE_PROVIDER_SERIALIZATION_CLASS, e); } try { result.setEventSenderFactoryClassName(config.getString(EVENT_SENDER_FACTORY_CLASS, EVENT_SENDER_FACTORY_CLASS_DEFAULT)); } catch (Exception e) { throw F2SConfigurationException.with(config, EVENT_SENDER_FACTORY_CLASS, e); } try { result.setConnectionParametersFactoryClassName(config.getString(CONNECTION_PARAMETERS_FACTORY_CLASS, CONNECTION_PARAMETERS_FACTORY_CLASS_DEFAULT)); } catch (Exception e) { throw F2SConfigurationException.with(config, CONNECTION_PARAMETERS_FACTORY_CLASS, e); } result.configuration = config; return result; } /** * Empty constructor - initializes with default values when available */ public StormSinkConfiguration() { batchSize = BATCH_SIZE_DEFAULT; locationServiceFactoryClassName = LOCATION_SERVICE_FACTORY_CLASS_DEFAULT; serviceProviderSerializationClassName = SERVICE_PROVIDER_SERIALIZATION_CLASS_DEFAULT; connectionParametersFactoryClassName = CONNECTION_PARAMETERS_FACTORY_CLASS_DEFAULT; eventSenderFactoryClassName = EVENT_SENDER_FACTORY_CLASS_DEFAULT; configuration = new BaseConfiguration(); } /** * Copy constructor * * @param other * the configuration to copy */ public StormSinkConfiguration(final StormSinkConfiguration other) { batchSize = other.batchSize; locationServiceFactoryClassName = other.locationServiceFactoryClassName; serviceProviderSerializationClassName = other.serviceProviderSerializationClassName; connectionParametersFactoryClassName = other.connectionParametersFactoryClassName; eventSenderFactoryClassName = other.eventSenderFactoryClassName; configuration = new MapConfiguration(ConfigurationConverter.getMap(other.configuration)); } /** * @return The number of events per transaction */ public int getBatchSize() { return batchSize; } /** * @param batchSize * See {@link #getBatchSize()} */ public void setBatchSize(int batchSize) { Preconditions.checkArgument(batchSize > 0, "Batch-size must be strictly positive"); this.batchSize = batchSize; } /** * @return The class name of the location service factory */ public String getLocationServiceFactoryClassName() { return locationServiceFactoryClassName; } /** * @param locationServiceFactoryClassName * See {@link #getLocationServiceFactoryClassName()} * @throws ClassNotFoundException * If the class specified is not found in the classpath */ public void setLocationServiceFactoryClassName(String locationServiceFactoryClassName) throws ClassNotFoundException { Class<?> locationServiceFactoryClass = Class.forName(locationServiceFactoryClassName); Preconditions.checkArgument(LocationServiceFactory.class.isAssignableFrom(locationServiceFactoryClass), "The class must implement " + LocationServiceFactory.class.getCanonicalName()); this.locationServiceFactoryClassName = locationServiceFactoryClassName; } /** * @return The class name of the service provider serialization */ public String getServiceProviderSerializationClassName() { return serviceProviderSerializationClassName; } /** * @param serviceProviderSerializationClassName * See {@link #getServiceProviderSerializationClassName()} * @throws ClassNotFoundException * If the class specified is not found in the classpath */ public void setServiceProviderSerializationClassName(String serviceProviderSerializationClassName) throws ClassNotFoundException { Class<?> serviceProviderSerializationClass = Class.forName(serviceProviderSerializationClassName); Preconditions.checkArgument(ServiceProviderSerialization.class.isAssignableFrom(serviceProviderSerializationClass), "The class must implement " + ServiceProviderSerialization.class.getCanonicalName()); this.serviceProviderSerializationClassName = serviceProviderSerializationClassName; } /** * @return The class name of the event sender factory */ public String getEventSenderFactoryClassName() { return eventSenderFactoryClassName; } /** * @param eventSenderFactoryClassName * See {@link #getEventSenderFactoryClassName()} * @throws ClassNotFoundException * If the class specified is not found in the classpath */ public void setEventSenderFactoryClassName(String eventSenderFactoryClassName) throws ClassNotFoundException { Class<?> eventSenderFactoryClass = Class.forName(eventSenderFactoryClassName); Preconditions.checkArgument(EventSenderFactory.class.isAssignableFrom(eventSenderFactoryClass), "The class must implement " + EventSenderFactory.class.getCanonicalName()); this.eventSenderFactoryClassName = eventSenderFactoryClassName; } /** * @return The class name of the connection parameters factory */ public String getConnectionParametersFactoryClassName() { return connectionParametersFactoryClassName; } /** * @param connectionParametersFactoryClassName * See {@link #getConnectionParametersFactoryClassName()} * @throws ClassNotFoundException * If the class specified is not found in the classpath */ public void setConnectionParametersFactoryClassName(String connectionParametersFactoryClassName) throws ClassNotFoundException { Class<?> connectionParametersFactoryClass = Class.forName(connectionParametersFactoryClassName); Preconditions.checkArgument(ConnectionParametersFactory.class.isAssignableFrom(connectionParametersFactoryClass), "The class must implement " + ConnectionParametersFactory.class.getCanonicalName()); this.connectionParametersFactoryClassName = connectionParametersFactoryClassName; } /** * @see com.google.common.base.Supplier#get() * @return This object as a {@link Configuration} */ public Configuration get() { return configuration; } /** * @param configuration * The {@link FlumeSpout} configuration as a * {@link StormSinkConfiguration} */ public void setConfiguration(Configuration configuration) { this.configuration = configuration; } }