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

org.ow2.petals.microkernel.configuration.ConfigurationServiceImpl Maven / Gradle / Ivy

There is a newer version: 4.3.0
Show newest version
/**
 * Copyright (c) 2007-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library 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 Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.microkernel.configuration;

import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
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.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;

import org.objectweb.fractal.fraclet.annotations.Component;
import org.objectweb.fractal.fraclet.annotations.Interface;
import org.objectweb.fractal.fraclet.annotations.Lifecycle;
import org.objectweb.fractal.fraclet.types.Step;
import org.ow2.petals.commons.log.PetalsExecutionContext;
import org.ow2.petals.launcher.api.server.conf.ConfigurationProperties;
import org.ow2.petals.microkernel.api.communication.sharedarea.SharedAreaService;
import org.ow2.petals.microkernel.api.communication.topology.TopologyService;
import org.ow2.petals.microkernel.api.configuration.ConfigurationService;
import org.ow2.petals.microkernel.api.configuration.ContainerConfiguration;
import org.ow2.petals.microkernel.api.configuration.ContainerConfigurationListener;
import org.ow2.petals.microkernel.api.configuration.DomainConfiguration;
import org.ow2.petals.microkernel.api.configuration.exception.ConfigurationException;
import org.ow2.petals.microkernel.api.configuration.exception.MissingServerPropertyException;
import org.ow2.petals.microkernel.api.jbi.messaging.RouterService;
import org.ow2.petals.microkernel.api.transport.FastRemoteTransportService;
import org.ow2.petals.microkernel.api.util.ConfigurationServiceUtils;
import org.ow2.petals.topology.TopologyBuilder;
import org.ow2.petals.topology.TopologyException;
import org.ow2.petals.topology.TopologyHelper;
import org.ow2.petals.topology.generated.Container;
import org.ow2.petals.topology.generated.Topology;

import com.ebmwebsourcing.easycommons.log.LoggingUtil;
import com.ebmwebsourcing.easycommons.properties.PropertiesException;
import com.ebmwebsourcing.easycommons.properties.PropertiesHelper;

/**
 * 

* The Configuration service that handles the configuration of the local PEtALS * container. *

*

* At its starting, it retrieves the configuration from the {@link Topology} and * the local container configuration (ie, content of the file * 'server.properties'), it performs a first level validation of the * consistency, then it fill the local {@link ContainerConfiguration}. *

* * @author Roland NAUDIN - EBM WebSourcing * @author Christophe Hamerling - EBM WebSourcing * @author Charles Casadei - EBM WebSourcing * @since Petals 2.0 */ @Component(provides = @Interface(name = "service", signature = ConfigurationService.class)) public class ConfigurationServiceImpl implements ConfigurationService { /** * File name, in the working area, of the persisted topology definition */ private static final String PERSISTED_TOPOLOGY_DEFINITION = "topology.xml"; /** * Logging utilities */ protected final LoggingUtil log = new LoggingUtil(Logger.getLogger(ConfigurationService.COMPONENT_LOGGER_NAME)); /** * The configuration of the current container */ private final ContainerConfiguration containerConfiguration = new ContainerConfiguration(); /** * The domain configuration of the domain for which the current container is a member. */ private DomainConfiguration domainConfiguration = new DomainConfiguration(); /** * List of remote container configuration created from the topology. Key is the container name. * * TODO this maybe should be moved to {@link TopologyService} or even {@link SharedAreaService}... * {@link ConfigurationService} is more used to hold non-dynamic information! */ private final ConcurrentMap knownContainers = new ConcurrentHashMap<>(); /** * The local topology read from the local topology definition (i.e., default topology.xml or persisted one) */ private Topology localTopology; private final List containerConfigListeners = Collections .synchronizedList(new ArrayList()); @Override public void registerContainerConfigurationListener(final ContainerConfigurationListener listener) { this.containerConfigListeners.add(listener); } @Override public void deregisterContainerConfigurationListener(final ContainerConfigurationListener listener) { this.containerConfigListeners.remove(listener); } @Override public ContainerConfiguration getContainerConfiguration() { return this.containerConfiguration; } @Override public Map getAllServerProperties() { final Map containerLocalProperties = new HashMap<>(); containerLocalProperties.put(ConfigurationProperties.CONTAINER_NAME, this.containerConfiguration.getName()); containerLocalProperties.put(ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME, this.containerConfiguration.getDataRootPath()); containerLocalProperties.put(ConfigurationProperties.REPOSITORY_PATH_PROPERTY_NAME, this.containerConfiguration.getRepositoryDirectoryPath()); containerLocalProperties.put(ConfigurationProperties.WORKING_AREA_PATH_PROPERTY_NAME, this.containerConfiguration.getWorkDirectoryPath()); containerLocalProperties.put(ConfigurationProperties.EXCHANGE_VALIDATION, Boolean.toString(this.containerConfiguration.isExchangeValidation())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_QUEUE_MAXSIZE, Integer.toString(this.containerConfiguration.getTransporterQueueMaxSize())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_QUEUE_OFFERING_TIMEOUT, Long.toString(this.containerConfiguration.getTransporterQueueOfferingTimeout())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_RECEIVERS, Integer.toString(this.containerConfiguration.getTCPReceivers())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_LISTEN, this.containerConfiguration.getTCPListen()); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_SENDERS, Integer.toString(this.containerConfiguration.getTCPSenders())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_CONNECTION_TIMEOUT, Long.toString(this.containerConfiguration.getTCPConnectionTimeout())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_SEND_TIMEOUT, Long.toString(this.containerConfiguration.getTCPSendTimeout())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_SEND_EVICTOR_DELAY, Long.toString(this.containerConfiguration.getTCPSenderEvictorDelay())); containerLocalProperties.put(ConfigurationProperties.TRANSPORT_TCP_SEND_EVICTABLE_DELAY, Long.toString(this.containerConfiguration.getTCPSenderEvictableDelay())); containerLocalProperties.put(ConfigurationProperties.ROUTER_QOS, this.containerConfiguration.getRouterQOS()); containerLocalProperties.put(ConfigurationProperties.ROUTER_STRATEGY, this.containerConfiguration.getRouterStrategy()); containerLocalProperties.put(ConfigurationProperties.ROUTER_SEND_ATTEMPT, Short.toString(this.containerConfiguration.getRouterSendAttempt())); containerLocalProperties.put(ConfigurationProperties.ROUTER_SEND_DELAY, Integer.toString(this.containerConfiguration.getRouterSendDelay())); containerLocalProperties.put(ConfigurationProperties.TASK_TIMEOUT, Long.toString(this.containerConfiguration.getTaskTimeout())); containerLocalProperties.put(ConfigurationProperties.CLASSLOADER_ISOLATED, Boolean.toString(this.containerConfiguration.isIsolateJBIClassLoaders())); containerLocalProperties.put(ConfigurationProperties.SSL_KEY_PASSWORD, this.containerConfiguration.getSSLKeyPassword()); containerLocalProperties.put(ConfigurationProperties.SSL_KEYSTORE_FILE, this.containerConfiguration.getSSLKeystore()); containerLocalProperties.put(ConfigurationProperties.SSL_KEYSTORE_PASSWORD, this.containerConfiguration.getSSLKeystorePassword()); containerLocalProperties.put(ConfigurationProperties.SSL_TRUSTSTORE_FILE, this.containerConfiguration.getSSLTruststore()); containerLocalProperties.put(ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD, this.containerConfiguration.getSSLTruststorePassword()); containerLocalProperties.put(ConfigurationProperties.RECOVERY_CORE_POOL_SIZE, Integer.toString(this.containerConfiguration.getRecoveryCorePoolSize())); containerLocalProperties.put(ConfigurationProperties.RECOVERY_KEEP_ALIVE_TIME, Long.toString(this.containerConfiguration.getRecoveryKeepAliveTime())); containerLocalProperties.put(ConfigurationProperties.TOPOLOGY_LOCKS_MAX_WAIT_TIME, Integer.toString(this.containerConfiguration.getTopologyLocksMaxWaitTime())); // Add user properties final Map userConfiguration = this.containerConfiguration .getUserConfiguration(); if (userConfiguration != null) { containerLocalProperties.putAll(userConfiguration); } // Add extra properties final Map extraConfiguration = this.containerConfiguration .getExtraConfiguration(); if (extraConfiguration != null) { containerLocalProperties.putAll(extraConfiguration); } return containerLocalProperties; } @Override public Properties getServerProperties() { final Properties serverProperties = new Properties(); for (final Map.Entry entry : this.getAllServerProperties().entrySet()) { final String value = entry.getValue(); if (value != null) { serverProperties.setProperty(entry.getKey(), value); } } return serverProperties; } @Override public ContainerConfiguration getContainerConfiguration(final String containerName) { final ContainerConfiguration result; if (this.containerConfiguration.getName().equals(containerName)) { result = this.getContainerConfiguration(); } else { result = this.knownContainers.get(containerName); } return result; } @Override public synchronized Set getContainersConfiguration() { final Set res = new HashSet<>(this.knownContainers.values()); res.add(this.containerConfiguration); return res; } @Override public synchronized DomainConfiguration getDomainConfiguration() { this.log.call(); return this.domainConfiguration; } @Override public synchronized Topology getLocalTopology() { this.log.call(); return this.localTopology; } @Lifecycle(step = Step.START) public void start() throws Exception { this.log.call(); } @Lifecycle(step = Step.STOP) public void stop() { this.log.call(); } @Override public void loadConfiguration(final Properties serverLocalProperties, final Topology topology) throws ConfigurationException { assert serverLocalProperties != null; assert topology != null; this.log.start(); try { initializeLocalProperties(this.containerConfiguration, serverLocalProperties, this.log); // Checks if the container name has been set in the // server local configuration (ie. content of 'server.properties' // or equivalent) or as a system property final String containerName = this.containerConfiguration.getName(); if (containerName == null || containerName.isEmpty()) { throw new MissingServerPropertyException( ConfigurationProperties.CONTAINER_NAME, "The property '" + ConfigurationProperties.CONTAINER_NAME + "' must be set in the server local configuration (ie. in the content of file 'server.properties' or equivalent) or as system property"); } // Check if a persisted topology definition exists final String workingAreaValue = this.containerConfiguration.getWorkDirectoryPath(); final File workingArea = new File(workingAreaValue); if (workingArea.exists()) { if (workingArea.isDirectory()) { final File persistedTopologyFile = new File(workingArea, PERSISTED_TOPOLOGY_DEFINITION); if (persistedTopologyFile.exists()) { if (persistedTopologyFile.isFile()) { try { this.log.debug("A persisted topology definition exists, we use it."); this.localTopology = TopologyBuilder.createTopology(persistedTopologyFile); } catch (final TopologyException e) { throw new ConfigurationException(String.format( "An error occurs parsing the persisted topology definition '%s'.", persistedTopologyFile.getAbsolutePath()), e); } } else { throw new ConfigurationException(String.format( "Invalid persisted topology definition '%s' (not a file).", persistedTopologyFile.getAbsolutePath())); } } else { this.log.debug("No persisted topology definition exists."); this.localTopology = topology; } } else { throw new ConfigurationException(String.format("Invalid working area '%s' (not a directory).", workingAreaValue)); } } else { this.log.info(String .format("The working area '%s' does not exists. Probably it's the first startup of the container, or the data area has been cleaned manually.", workingArea.getAbsoluteFile())); if (!workingArea.mkdirs()) { log.warning(String.format( "Unable to create the working area '%s'. Potential problems can occurs later.", workingAreaValue)); } this.localTopology = topology; } // all these validations will be done again (and must be because we are maybe moving between // topologies) when the shared area update the topology with updateTopology, but let's validate as early as // we can ConfigurationServiceUtils.validateTopology(this.containerConfiguration, this.localTopology); // this is needed so that the domain contains the correct informations (including shared area specificities) // for the shared area to initialise ConfigurationServiceUtils.initializeDomainConfiguration(this.domainConfiguration, this.localTopology); // this is needed to initialise things like ports and stuffs (TODO that could actually be in the server conf // and not the topology.... but putting it in the topology avoids duplication...) ConfigurationServiceUtils.initializeContainerConfiguration(this.containerConfiguration, this.localTopology); // post validate platform configuration validateContainerConfiguration(this.containerConfiguration, this.log); // TODO this doesn't really make sense to update that now, because updateTopology will do it with the real // informations when it will be called during the shared area startup // but many components relies on this information being filled after loadConfiguration has been called // e.g.: sometimes, to start the shared area, we need the embedded registry to be started, and to start it, // we need to know this information (it is activated if and only if it is needed) this.updateKnownContainers(this.localTopology); if (this.log.isConfigEnabled()) { this.log.config("Configuration used: " + this.containerConfiguration.toString()); } } finally { this.log.end(); } } /** *

* Registers the containers defined in the domain. *

*

* If a container is already registered but not declared in the topology, it is unregistered *

* * @param topology * A topology configuration coming from its XML definition. Can not be null. */ private void updateKnownContainers(final Topology topology) { // add the containers of the topology (except us) for (final Container container : topology.getDomain().getContainer()) { if (!container.getName().equals(this.containerConfiguration.getName())) { final ContainerConfiguration cc = new ContainerConfiguration(); ConfigurationServiceUtils.initializeContainerConfiguration(cc, container); this.knownContainers.put(cc.getName(), cc); } } // remove containers not here anymore final Iterator itContainerCfg = this.knownContainers.values().iterator(); while (itContainerCfg.hasNext()) { if (TopologyHelper.findContainer(itContainerCfg.next().getName(), topology) == null) { // The container is not in the topology anymore itContainerCfg.remove(); } } } /** * Initialize a container configuration with the server properties. * * @param containerConfiguration * The container configuration to initialize. Can be null. * @param serverLocalProperties * The local properties of the current container (ie: the content of 'server.properties' or equivalent). * Can be null. * @throws MissingServerPropertyException * A required server property is missing. * @throws ConfigurationException * An error occurs about a property value */ private static void initializeLocalProperties(final ContainerConfiguration containerConfiguration, final Properties serverLocalProperties, final LoggingUtil log) throws MissingServerPropertyException, ConfigurationException { log.start(); final Map userProperties = new HashMap<>(); final Map extraProperties = new HashMap<>(); if (serverLocalProperties != null) { for (final Map.Entry entry : serverLocalProperties.entrySet()) { final Object keyObj = entry.getKey(); final String value = (String) entry.getValue(); if (keyObj instanceof String) { final String key = (String) keyObj; if (key.equals(ConfigurationProperties.CONTAINER_NAME)) { containerConfiguration.setName(value); } else if (key .equals(ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME)) { containerConfiguration.setDataRootPath(value); } else if (key.equals(ConfigurationProperties.REPOSITORY_PATH_PROPERTY_NAME)) { containerConfiguration.setRepositoryDirectoryPath(value); } else if (key.equals(ConfigurationProperties.WORKING_AREA_PATH_PROPERTY_NAME)) { containerConfiguration.setWorkDirectoryPath(value); } else if (key.equals(ConfigurationProperties.EXCHANGE_VALIDATION)) { containerConfiguration.setExchangeValidation(Boolean .parseBoolean(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_QUEUE_MAXSIZE)) { containerConfiguration.setTransporterQueueMaxSize(Integer .parseInt(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_QUEUE_OFFERING_TIMEOUT)) { containerConfiguration.setTransporterQueueOfferingTimeout(Long .parseLong(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_RECEIVERS)) { containerConfiguration.setTCPReceivers(Integer.parseInt(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_RECEIVER_KEEP_ALIVE_TIME)) { containerConfiguration.setTCPReceiversKeepAlive(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_SENDERS)) { containerConfiguration.setTCPSenders(Integer.parseInt(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_LISTEN)) { containerConfiguration.setTCPListen(value); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_CONNECTION_TIMEOUT)) { containerConfiguration.setTCPConnectionTimeout(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_SEND_TIMEOUT)) { containerConfiguration.setTCPSendTimeout(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.TRANSPORT_TCP_SEND_EVICTOR_DELAY)) { containerConfiguration.setTCPSenderEvictorDelay(Long.parseLong(value)); } else if (key .equals(ConfigurationProperties.TRANSPORT_TCP_SEND_EVICTABLE_DELAY)) { containerConfiguration.setTCPSenderEvictableDelay(Long .parseLong(value)); } else if (key.equals(ConfigurationProperties.ROUTER_QOS)) { containerConfiguration.setRouterQOS(value); } else if (key.equals(ConfigurationProperties.ROUTER_STRATEGY)) { containerConfiguration.setRouterStrategy(value); } else if (key.equals(ConfigurationProperties.ROUTER_SEND_ATTEMPT)) { containerConfiguration.setRouterSendAttempt(Short.parseShort(value)); } else if (key.equals(ConfigurationProperties.ROUTER_SEND_DELAY)) { containerConfiguration.setRouterSendDelay(Integer.parseInt(value)); } else if (key.equals(ConfigurationProperties.ROUTER_STOP_TRAFFIC_DELAY)) { containerConfiguration.setRouterStopTrafficDelay(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.ROUTER_PAUSE_TRAFFIC_DELAY)) { containerConfiguration.setRouterPauseTrafficDelay(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.TASK_TIMEOUT)) { containerConfiguration.setTaskTimeout(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.CLASSLOADER_ISOLATED)) { containerConfiguration.setIsolateJBIClassLoaders(Boolean .parseBoolean(value)); } else if (key.equals(ConfigurationProperties.SSL_KEY_PASSWORD)) { containerConfiguration.setSSLKeyPassword(value); } else if (key.equals(ConfigurationProperties.SSL_KEYSTORE_FILE)) { containerConfiguration.setSSLKeystore(value); } else if (key.equals(ConfigurationProperties.SSL_KEYSTORE_PASSWORD)) { containerConfiguration.setSSLKeystorePassword(value); } else if (key.equals(ConfigurationProperties.SSL_TRUSTSTORE_FILE)) { containerConfiguration.setSSLTruststore(value); } else if (key.equals(ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD)) { containerConfiguration.setSSLTruststorePassword(value); } else if (key.equals(ConfigurationProperties.TOPOLOGY_PASSPHRASE)) { containerConfiguration.setTopologyPassPhrase(serverLocalProperties .getProperty(key, null)); } else if (key.equals(ConfigurationProperties.TOPOLOGY_LOCKS_MAX_WAIT_TIME)) { containerConfiguration.setTopologyLocksMaxWaitTime(Integer.parseInt(value)); } else if (key.equals(ConfigurationProperties.TOPOLOGY_PINGER_START_DELAY)) { containerConfiguration.setTopologyPingerStartDelay(Long.parseLong(value)); } else if (key.equals(ConfigurationProperties.TOPOLOGY_PINGER_PERIOD_DELAY)) { containerConfiguration.setTopologyPingerPeriodDelay(Long.parseLong(value)); } else if (key.startsWith(ConfigurationProperties.USER_CONFIG_PREFIX + ".")) { userProperties.put(key, value); } else if (key.equals(ConfigurationProperties.RECOVERY_CORE_POOL_SIZE)) { containerConfiguration .setRecoveryCorePoolSize(Integer.parseInt(value)); } else if (key.equals(ConfigurationProperties.RECOVERY_KEEP_ALIVE_TIME)) { containerConfiguration.setRecoveryKeepAliveTime(Long.parseLong(value)); } else { extraProperties.put(key, value); } } } } // If the container name is not defined as server property, try to get it as system property if (containerConfiguration.getName() == null) { containerConfiguration.setName(System.getProperty(ConfigurationProperties.CONTAINER_NAME)); } // Set the container name into the Petals MDC as soon as possible if (containerConfiguration.getName() != null) { PetalsExecutionContext.putContainerName(containerConfiguration.getName()); } if (userProperties.size() > 0) { containerConfiguration.setUserConfiguration(userProperties); } containerConfiguration.setExtraConfiguration(extraProperties); // Set default value to not set required properties try { if (containerConfiguration.getRepositoryDirectoryPath() == null) { final String dataRootPath = containerConfiguration.getDataRootPath(); if (dataRootPath != null && !dataRootPath.isEmpty()) { containerConfiguration.setRepositoryDirectoryPath(PropertiesHelper .resolveString(ConfigurationProperties.DEFAULT_REPOSITORY_PATH, serverLocalProperties)); } else { throw new MissingServerPropertyException(ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME); } } if (containerConfiguration.getWorkDirectoryPath() == null) { final String dataRootPath = containerConfiguration.getDataRootPath(); if (dataRootPath != null && !dataRootPath.isEmpty()) { containerConfiguration.setWorkDirectoryPath(PropertiesHelper.resolveString( ConfigurationProperties.DEFAULT_WORKING_AREA_PATH, serverLocalProperties)); } else { throw new MissingServerPropertyException(ConfigurationProperties.DATA_ROOT_DIRECTORY_PROPERTY_NAME); } } final String workingRootPath = containerConfiguration.getWorkDirectoryPath(); if (workingRootPath == null || workingRootPath.isEmpty()) { // TODO this is not really used in practice (it was in the past but not anymore...) // still let's fail if it's missing throw new MissingServerPropertyException(ConfigurationProperties.WORKING_AREA_PATH_PROPERTY_NAME); } } catch (final PropertiesException e) { throw new ConfigurationException(e); } log.end(); } /** *

* Post validation of a container configuration, based on {@link ContainerConfiguration} content: *

    *
  • check the coherence of the container configuration,
  • *
  • create required directories if needed.
  • *
*

* * @throws ConfigurationException * Something is wrong */ private static void validateContainerConfiguration(final ContainerConfiguration containerConfiguration, final LoggingUtil log) throws ConfigurationException { // validate the routing policy and transporter requirements if (RouterService.FAST_POLICY.equals(containerConfiguration.getRouterQOS()) && (containerConfiguration.getTCPPort() == 0)) { throw new ConfigurationException("The router transport QOS '" + RouterService.FAST_POLICY + "' is not compatible with the transport protocols configuration"); } if (RouterService.SECURE_POLICY.equals(containerConfiguration.getRouterQOS())) { throw new ConfigurationException("The default router QOS '" + RouterService.SECURE_POLICY + "' is not compatible with the transport protocols configuration"); } if (RouterService.RELIABLE_POLICY.equals(containerConfiguration.getRouterQOS())) { throw new ConfigurationException("The default router QOS '" + RouterService.RELIABLE_POLICY + "' is not compatible with the transport protocols configuration"); } // if tcp listen equals null, then host will be used and it is thus compatible final String tcpListen = containerConfiguration.getTCPListen(); if (containerConfiguration.getTCPPort() > 0 && !FastRemoteTransportService.DEFAULT_RECEIVER_LISTENING_ITF.equals(tcpListen)) { boolean hostLoopback = false; final String containerHost = containerConfiguration.getHost(); try { hostLoopback = InetAddress.getByName(containerHost).isLoopbackAddress(); } catch (final UnknownHostException e) { log.warning("The topology's container hostname is not resolvable: " + containerHost); } boolean listenLoopback = false; try { listenLoopback = InetAddress.getByName(tcpListen).isLoopbackAddress(); } catch (final UnknownHostException e) { log.warning( "The container TCP transporter listening interface is not a resolvable hostname: " + tcpListen); } if (listenLoopback && !hostLoopback) { throw new ConfigurationException( "The container TCP transporter listening interface is on the loopback interface (as " + tcpListen + ") but it exposes itself in the topology as the external " + containerHost); } if (!listenLoopback && hostLoopback) { throw new ConfigurationException( "The container TCP transporter listening interface is on an external interface (as " + tcpListen + ") but it exposes itself in the topology as local loopback " + containerHost); } } } @Override public void reconfigureDomain(final Topology topology) throws ConfigurationException { assert topology != null; this.log.debug("Updating domain configuration (1/2: shared area and domain name) ..."); ConfigurationServiceUtils.initializeDomainConfiguration(this.domainConfiguration, topology); this.log.debug("Domain configuration (1/2: shared area and domain name) updated"); // note, we initalize the domain conf before because there could be an exception! this.persistTopology(topology); this.log.debug( "Updating domain configuration (2/2: registering locally other containers of the new domain) ..."); this.updateKnownContainers(topology); this.log.debug("Domain configuration (2/2: registering locally other containers of the new domain) updated"); } @Override public void updateTopology(final Topology topology, final boolean validate) throws ConfigurationException { assert topology != null; if (validate) { final DomainConfiguration targetDomain = new DomainConfiguration(); ConfigurationServiceUtils.initializeDomainConfiguration(targetDomain, topology); // this verify all the domain configuration parameters that could be different ConfigurationServiceUtils.verifyDomainConfiguration(targetDomain, this.domainConfiguration); ConfigurationServiceUtils.validateTopology(topology); // Check that the current container configuration of the new topology is compliant with the existing one // Note: it is important in particular when joining a topology because maybe what the topology expects of us // (for example if it's a static topology) is different from what we offer final ContainerConfiguration newContainerConfiguration = new ContainerConfiguration(); newContainerConfiguration.setName(this.containerConfiguration.getName()); ConfigurationServiceUtils.initializeContainerConfiguration(newContainerConfiguration, topology); ConfigurationServiceUtils.verifyContainer(newContainerConfiguration, this.containerConfiguration); } // The dynamic topology is compliant with the one already known // we update the whole configuration this.persistTopology(topology); this.updateKnownContainers(topology); } @Override public boolean isSecurityTopologyPassphraseOk(final String securityPassPhrase) { // Check security final boolean isSecurityOk; if (securityPassPhrase == null || securityPassPhrase.isEmpty()) { isSecurityOk = false; } else { final String containerTopologyPassPhrase = this.containerConfiguration.getTopologyPassPhrase(); if (containerTopologyPassPhrase == null || containerTopologyPassPhrase.isEmpty() || !containerTopologyPassPhrase.equals(securityPassPhrase)) { isSecurityOk = false; } else { isSecurityOk = true; } } return isSecurityOk; } private void persistTopology(final Topology topology) throws ConfigurationException { this.log.debug("Persisting dynamic topology ..."); final Topology clone = (Topology) topology.clone(); final String workingAreaValue = this.containerConfiguration.getWorkDirectoryPath(); final File workingArea = new File(workingAreaValue); if (workingArea.exists()) { if (workingArea.isDirectory()) { final File persistedTopologyFile = new File(workingArea, PERSISTED_TOPOLOGY_DEFINITION); if (persistedTopologyFile.exists()) { if (!persistedTopologyFile.isFile()) { throw new ConfigurationException(String.format( "Invalid persisted topology definition '%s' (not a file).", persistedTopologyFile.getAbsolutePath())); } } try { this.log.debug("Persisting the topology definition: " + persistedTopologyFile.getAbsolutePath()); TopologyBuilder.marshallTopologyFile(persistedTopologyFile, clone); // this is now the new local topology this.localTopology = clone; } catch (final TopologyException e) { throw new ConfigurationException(String.format( "An error occurs persisting the topology definition in file '%s'.", persistedTopologyFile.getAbsolutePath()), e); } } else { throw new ConfigurationException(String.format("Invalid working area '%s' (not a directory).", workingAreaValue)); } } else { throw new ConfigurationException(String.format("The working area '%s' does not exists.", workingAreaValue)); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy