Java tutorial
/* * This file is part of dropwizard-curator. * * dropwizard-curator is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dropwizard-curator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with dropwizard-curator. If not, see <http://www.gnu.org/licenses/>. */ package com.pandich.dropwizard.curator.refresh; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.pandich.dropwizard.curator.CuratorConfiguration; import com.pandich.dropwizard.curator.CuratorInject; import com.pandich.dropwizard.curator.CuratorRootConfiguration; import com.pandich.dropwizard.curator.PropertySources.PropertySource; import com.pandich.dropwizard.curator.mapper.CuratorMapper; import org.apache.commons.lang3.reflect.ConstructorUtils; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.UnhandledErrorListener; import org.apache.curator.framework.state.ConnectionState; import org.apache.curator.framework.state.ConnectionStateListener; import org.apache.curator.retry.RetryNTimes; import org.reflections.Reflections; import org.reflections.scanners.FieldAnnotationsScanner; import org.reflections.scanners.MethodAnnotationsScanner; import org.reflections.scanners.SubTypesScanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; import static com.pandich.dropwizard.curator.CuratorBundle.BASE_PROJECT_PACKAGE; import static com.pandich.dropwizard.curator.refresh.FieldRefresher.fieldIsValid; import static com.pandich.dropwizard.curator.refresh.MethodRefresher.methodIsValid; public class CuratorRefresherManager<T extends CuratorRootConfiguration> implements UnhandledErrorListener, ConnectionStateListener { private static final Logger log = LoggerFactory.getLogger(CuratorRefresherManager.class); private static void initialSetup(final List<Class<? extends CuratorRootConfiguration>> configurationClasses, final Refresher<Field> fieldRefresher, final Refresher<Method> methodRefresher) throws Exception { for (final Class<? extends CuratorRootConfiguration> configurationClass : configurationClasses) { log.debug("configuration class: {}", configurationClass.getSimpleName()); final Reflections fieldReflections = new Reflections(configurationClass, new FieldAnnotationsScanner()); for (final Field field : Sets.filter(fieldReflections.getFieldsAnnotatedWith(CuratorInject.class), fieldIsValid)) { fieldRefresher.refresh(configurationClass, field); } final Reflections methodReflections = new Reflections(configurationClass, new MethodAnnotationsScanner()); for (final Method method : Sets.filter(methodReflections.getMethodsAnnotatedWith(CuratorInject.class), methodIsValid)) { methodRefresher.refresh(configurationClass, method); } } if (log.isDebugEnabled()) { for (final Map.Entry<Class, ConcurrentMap<String, PropertySource>> classEntry : fieldRefresher.propertySources) { for (final Map.Entry<String, PropertySource> propertyEntry : classEntry.getValue().entrySet()) { log.debug("source: {}.{}={}", new Object[] { classEntry.getKey(), propertyEntry.getKey(), propertyEntry.getValue() }); } } for (final Map.Entry<Class, ConcurrentMap<String, PropertySource>> classEntry : methodRefresher.propertySources) { for (final Map.Entry<String, PropertySource> propertyEntry : classEntry.getValue().entrySet()) { log.debug("source: {}.{}({})", new Object[] { classEntry.getKey(), propertyEntry.getKey(), propertyEntry.getValue() }); } } } } public CuratorRefresherManager(final T configuration, final String baseConfigurationPackage) throws Exception { final CuratorConfiguration curatorConfiguration = configuration.getCurator(); final CuratorFramework client = CuratorFrameworkFactory.builder() .connectString(curatorConfiguration.connectionString) .connectionTimeoutMs((int) curatorConfiguration.connectionTimeout.toMilliseconds()) .sessionTimeoutMs((int) curatorConfiguration.sessionTimeout.toMilliseconds()) .retryPolicy(new RetryNTimes(curatorConfiguration.retryCount, (int) curatorConfiguration.retrySleepTime.toMilliseconds())) .build(); client.getUnhandledErrorListenable().addListener(this); client.getConnectionStateListenable().addListener(this); final Reflections mapperReflections = new Reflections(BASE_PROJECT_PACKAGE, baseConfigurationPackage, new SubTypesScanner()); final Set<Class<? extends CuratorMapper>> mapperTypes = mapperReflections .getSubTypesOf(CuratorMapper.class); final Map<Class<?>, CuratorMapper<?>> mappers = Maps.newHashMap(); for (final Class<? extends CuratorMapper> mapperType : mapperTypes) { final CuratorMapper<?> mapper = ConstructorUtils.invokeConstructor(mapperType); mappers.put(mapper.getType(), mapper); log.info("mapper: {} -> {}", mapperType.getSimpleName(), mapper.getType().getSimpleName()); } final Reflections configurationReflections = new Reflections(baseConfigurationPackage); final List<Class<? extends CuratorRootConfiguration>> configurationClasses = Lists.newArrayList(); configurationClasses.add(CuratorRootConfiguration.class); configurationClasses.addAll(configurationReflections.getSubTypesOf(CuratorRootConfiguration.class)); final List<Class<? extends CuratorRootConfiguration>> configurationClasses1 = ImmutableList .copyOf(configurationClasses); final Refresher<Field> fieldRefresher = new FieldRefresher(mappers, client, configuration); client.getCuratorListenable().addListener(fieldRefresher); final Refresher<Method> methodRefresher = new MethodRefresher(mappers, client, configuration); client.getCuratorListenable().addListener(methodRefresher); client.start(); initialSetup(configurationClasses1, fieldRefresher, methodRefresher); } @Override public void unhandledError(final String message, final Throwable e) { log.error(message, e); } @Override public void stateChanged(final CuratorFramework client, final ConnectionState newState) { log.debug("state changed to {}", newState.name()); } }