com.pandich.dropwizard.curator.refresh.CuratorRefresherManager.java Source code

Java tutorial

Introduction

Here is the source code for com.pandich.dropwizard.curator.refresh.CuratorRefresherManager.java

Source

/*
 * 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());
    }

}