All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.spi.discovery.impl.DefaultDiscoveryService Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * 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.hazelcast.spi.discovery.impl;

import com.hazelcast.config.DiscoveryConfig;
import com.hazelcast.config.DiscoveryStrategyConfig;
import com.hazelcast.config.InvalidConfigurationException;
import com.hazelcast.config.properties.PropertyDefinition;
import com.hazelcast.config.properties.ValidationException;
import com.hazelcast.config.properties.ValueValidator;
import com.hazelcast.core.HazelcastException;
import com.hazelcast.core.TypeConverter;
import com.hazelcast.logging.ILogger;
import com.hazelcast.spi.discovery.DiscoveryNode;
import com.hazelcast.spi.discovery.DiscoveryStrategy;
import com.hazelcast.spi.discovery.DiscoveryStrategyFactory;
import com.hazelcast.spi.discovery.NodeFilter;
import com.hazelcast.spi.discovery.integration.DiscoveryService;
import com.hazelcast.spi.discovery.integration.DiscoveryServiceSettings;
import com.hazelcast.util.ServiceLoader;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DefaultDiscoveryService
        implements DiscoveryService {

    private static final String SERVICE_LOADER_TAG = DiscoveryStrategyFactory.class.getCanonicalName();

    private final DiscoveryNode discoveryNode;
    private final ILogger logger;
    private final Iterable discoveryProviders;
    private final NodeFilter nodeFilter;

    public DefaultDiscoveryService(DiscoveryServiceSettings settings) {
        this.discoveryNode = settings.getDiscoveryNode();
        this.logger = settings.getLogger();
        this.nodeFilter = getNodeFilter(settings);
        this.discoveryProviders = loadDiscoveryProviders(settings);
    }

    @Override
    public void start() {
        for (DiscoveryStrategy discoveryStrategy : discoveryProviders) {
            discoveryStrategy.start();
        }
    }

    @Override
    public Iterable discoverNodes() {
        Set discoveryNodes = new HashSet();
        for (DiscoveryStrategy discoveryStrategy : discoveryProviders) {
            Iterable candidates = discoveryStrategy.discoverNodes();

            if (candidates != null) {
                for (DiscoveryNode candidate : candidates) {
                    if (validateCandidate(candidate)) {
                        discoveryNodes.add(candidate);
                    }
                }
            }
        }
        return discoveryNodes;
    }

    @Override
    public void destroy() {
        for (DiscoveryStrategy discoveryStrategy : discoveryProviders) {
            discoveryStrategy.destroy();
        }
    }

    private NodeFilter getNodeFilter(DiscoveryServiceSettings settings) {
        DiscoveryConfig discoveryConfig = settings.getDiscoveryConfig();
        ClassLoader configClassLoader = settings.getConfigClassLoader();
        if (discoveryConfig.getNodeFilter() != null) {
            return discoveryConfig.getNodeFilter();
        }
        if (discoveryConfig.getNodeFilterClass() != null) {
            try {
                ClassLoader cl = configClassLoader;
                if (cl == null) {
                    cl = DefaultDiscoveryService.class.getClassLoader();
                }

                String className = discoveryConfig.getNodeFilterClass();
                return (NodeFilter) cl.loadClass(className).newInstance();
            } catch (Exception e) {
                throw new RuntimeException("Failed to configure discovery node filter", e);
            }
        }
        return null;
    }

    private boolean validateCandidate(DiscoveryNode candidate) {
        return nodeFilter == null || nodeFilter.test(candidate);
    }

    private Iterable loadDiscoveryProviders(DiscoveryServiceSettings settings) {
        DiscoveryConfig discoveryConfig = settings.getDiscoveryConfig();
        ClassLoader configClassLoader = settings.getConfigClassLoader();

        try {
            Collection discoveryStrategyConfigs = new ArrayList(
                    discoveryConfig.getDiscoveryStrategyConfigs());

            Iterator iterator = ServiceLoader
                    .iterator(DiscoveryStrategyFactory.class, SERVICE_LOADER_TAG, configClassLoader);

            // Collect possible factories
            List factories = new ArrayList();
            while (iterator.hasNext()) {
                factories.add(iterator.next());
            }
            for (DiscoveryStrategyConfig config : discoveryStrategyConfigs) {
                DiscoveryStrategyFactory factory = config.getDiscoveryStrategyFactory();
                if (factory != null) {
                    factories.add(factory);
                }
            }

            List discoveryStrategies = new ArrayList();
            for (DiscoveryStrategyFactory factory : factories) {
                DiscoveryStrategy discoveryStrategy = buildDiscoveryProvider(factory, discoveryStrategyConfigs);
                if (discoveryStrategy != null) {
                    discoveryStrategies.add(discoveryStrategy);
                }
            }
            return discoveryStrategies;
        } catch (Exception e) {
            if (e instanceof ValidationException) {
                throw new InvalidConfigurationException("Invalid configuration", e);
            } else {
                throw new RuntimeException("Failed to configure discovery strategies", e);
            }
        }
    }

    private Map buildProperties(DiscoveryStrategyFactory factory, DiscoveryStrategyConfig config,
                                                    String className) {
        Collection propertyDefinitions = factory.getConfigurationProperties();
        if (propertyDefinitions == null) {
            return Collections.emptyMap();
        }

        Map properties = config.getProperties();
        Map mappedProperties = new HashMap();

        for (PropertyDefinition propertyDefinition : propertyDefinitions) {
            String propertyKey = propertyDefinition.key();
            Comparable value = properties.get(propertyKey);
            if (value == null) {
                if (!propertyDefinition.optional()) {
                    throw new HazelcastException(
                            "Missing property '" + propertyKey + "' on discovery strategy '" + className + "' configuration");
                }
                continue;
            }

            TypeConverter typeConverter = propertyDefinition.typeConverter();
            Comparable mappedValue = typeConverter.convert(value);

            ValueValidator validator = propertyDefinition.validator();
            if (validator != null) {
                validator.validate(mappedValue);
            }

            mappedProperties.put(propertyKey, mappedValue);
        }

        return mappedProperties;
    }

    private DiscoveryStrategy buildDiscoveryProvider(DiscoveryStrategyFactory factory,
                                                     Collection discoveryStrategyConfigs) {
        Class discoveryProviderType = factory.getDiscoveryStrategyType();
        String className = discoveryProviderType.getName();

        for (DiscoveryStrategyConfig config : discoveryStrategyConfigs) {
            String factoryClassName = getFactoryClassName(config);
            if (className.equals(factoryClassName)) {
                Map properties = buildProperties(factory, config, className);
                return factory.newDiscoveryStrategy(discoveryNode, logger, properties);
            }
        }
        return null;
    }

    private String getFactoryClassName(DiscoveryStrategyConfig config) {
        if (config.getDiscoveryStrategyFactory() != null) {
            DiscoveryStrategyFactory factory = config.getDiscoveryStrategyFactory();
            return factory.getDiscoveryStrategyType().getName();
        }
        return config.getClassName();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy