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

net.roboconf.dm.management.Manager Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
/**
 * Copyright 2013-2016 Linagora, Université Joseph Fourier, Floralis
 *
 * The present code is developed in the scope of the joint LINAGORA -
 * Université Joseph Fourier - Floralis research program and is designated
 * as a "Result" pursuant to the terms and conditions of the LINAGORA
 * - Université Joseph Fourier - Floralis research program. Each copyright
 * holder of Results enumerated here above fully & independently holds complete
 * ownership of the complete Intellectual Property rights applicable to the whole
 * of said Results, and may freely exploit it in any manner which does not infringe
 * the moral rights of the other copyright holders.
 *
 * 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 net.roboconf.dm.management;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;

import net.roboconf.core.Constants;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.api.IRandomMngr;
import net.roboconf.dm.internal.api.impl.ApplicationMngrImpl;
import net.roboconf.dm.internal.api.impl.ApplicationTemplateMngrImpl;
import net.roboconf.dm.internal.api.impl.AutonomicMngrImpl;
import net.roboconf.dm.internal.api.impl.CommandsMngrImpl;
import net.roboconf.dm.internal.api.impl.ConfigurationMngrImpl;
import net.roboconf.dm.internal.api.impl.DebugMngrImpl;
import net.roboconf.dm.internal.api.impl.InstancesMngrImpl;
import net.roboconf.dm.internal.api.impl.MessagingMngrImpl;
import net.roboconf.dm.internal.api.impl.NotificationMngrImpl;
import net.roboconf.dm.internal.api.impl.PreferencesMngrImpl;
import net.roboconf.dm.internal.api.impl.RandomMngrImpl;
import net.roboconf.dm.internal.api.impl.TargetHandlerResolverImpl;
import net.roboconf.dm.internal.api.impl.TargetsMngrImpl;
import net.roboconf.dm.internal.environment.messaging.DmMessageProcessor;
import net.roboconf.dm.internal.environment.messaging.RCDm;
import net.roboconf.dm.internal.tasks.CheckerHeartbeatsTask;
import net.roboconf.dm.internal.tasks.CheckerMessagesTask;
import net.roboconf.dm.management.api.IApplicationMngr;
import net.roboconf.dm.management.api.IApplicationTemplateMngr;
import net.roboconf.dm.management.api.IAutonomicMngr;
import net.roboconf.dm.management.api.ICommandsMngr;
import net.roboconf.dm.management.api.IConfigurationMngr;
import net.roboconf.dm.management.api.IDebugMngr;
import net.roboconf.dm.management.api.IInstancesMngr;
import net.roboconf.dm.management.api.IMessagingMngr;
import net.roboconf.dm.management.api.INotificationMngr;
import net.roboconf.dm.management.api.IPreferencesMngr;
import net.roboconf.dm.management.api.ITargetHandlerResolver;
import net.roboconf.dm.management.api.ITargetsMngr;
import net.roboconf.dm.management.events.IDmListener;
import net.roboconf.messaging.api.business.ListenerCommand;
import net.roboconf.target.api.TargetHandler;

/**
 * This class acts as a front-end to access the various features of the DM.
 * 

* This class is designed to work with OSGi, iPojo and Admin Config.
* But it can also be used programmatically. *

*

 * // Configure
 * Manager manager = new Manager();
 * manager.setMessagingType( "rabbitmq" );
 *
 * // Change the way we resolve handlers for deployment targetsMngr
 * manager.setTargetResolver( ... );
 *
 * // Connect to the messaging server
 * manager.start();
 * 
* * @author Noël - LIG * @author Pierre-Yves Gibello - Linagora * @author Vincent Zurczak - Linagora * @author Pierre Bourret - Université Joseph Fourier */ public class Manager { // Constants private static final long TIMER_PERIOD = 6000; // Injected by iPojo or Admin Config protected String messagingType; // Internal fields protected final Logger logger = Logger.getLogger( getClass().getName()); protected Timer timer; private RCDm messagingClient; // API access private final NotificationMngrImpl notificationMngr; private final MessagingMngrImpl messagingMngr; private final ApplicationMngrImpl applicationMngr; private final InstancesMngrImpl instancesMngr; private final IRandomMngr randomMngr; private final IPreferencesMngr preferencesMngr; private final IConfigurationMngr configurationMngr; private final IApplicationTemplateMngr applicationTemplateMngr; private final ITargetsMngr targetsMngr; private final IDebugMngr debugMngr; private final ICommandsMngr commandsMngr; private final IAutonomicMngr autonomicMngr; private final TargetHandlerResolverImpl defaultTargetHandlerResolver; /** * Constructor. */ public Manager() { super(); // Home-made DI. // We do not want to mix N frameworks. this.notificationMngr = new NotificationMngrImpl(); this.configurationMngr = new ConfigurationMngrImpl(); this.preferencesMngr = new PreferencesMngrImpl( this.configurationMngr ); this.randomMngr = new RandomMngrImpl( this.preferencesMngr ); this.messagingMngr = new MessagingMngrImpl(); this.defaultTargetHandlerResolver = new TargetHandlerResolverImpl(); this.targetsMngr = new TargetsMngrImpl( this.configurationMngr ); this.debugMngr = new DebugMngrImpl( this.messagingMngr, this.notificationMngr ); this.commandsMngr = new CommandsMngrImpl( this ); this.autonomicMngr = new AutonomicMngrImpl( this.commandsMngr, this.preferencesMngr ); this.applicationMngr = new ApplicationMngrImpl( this.notificationMngr, this.configurationMngr, this.targetsMngr, this.messagingMngr, this.randomMngr, this.autonomicMngr ); this.applicationTemplateMngr = new ApplicationTemplateMngrImpl( this.notificationMngr, this.targetsMngr, this.applicationMngr, this.configurationMngr ); this.applicationMngr.setApplicationTemplateMngr( this.applicationTemplateMngr ); this.instancesMngr = new InstancesMngrImpl( this.messagingMngr, this.notificationMngr, this.targetsMngr, this.randomMngr ); this.instancesMngr.setTargetHandlerResolver( this.defaultTargetHandlerResolver ); this.instancesMngr.setRuleBasedHandler( this.autonomicMngr ); } // iPojo stuff /** * Starts the manager. *

* It is invoked by iPojo when an instance becomes VALID. *

*/ public void start() { this.logger.info( "The DM is about to be launched." ); // Load the preferences this.preferencesMngr.loadProperties(); // Start the messaging DmMessageProcessor messageProcessor = new DmMessageProcessor( this ); this.messagingClient = new RCDm( this.applicationMngr ); this.messagingClient.associateMessageProcessor( messageProcessor ); this.messagingMngr.setMessagingClient( this.messagingClient ); // Run the timer this.timer = new Timer( "Roboconf's Management Timer", false ); this.timer.scheduleAtFixedRate( new CheckerMessagesTask( this.applicationMngr, this.messagingMngr ), 0, TIMER_PERIOD ); this.timer.scheduleAtFixedRate( new CheckerHeartbeatsTask( this.applicationMngr ), 0, Constants.HEARTBEAT_PERIOD ); // Configure the messaging reconfigure(); // Restore what is necessary this.applicationTemplateMngr.restoreTemplates(); this.applicationMngr.restoreApplications(); // We must update instance states after we restored applications restoreAllInstances(); this.logger.info( "The DM was launched." ); } /** * Stops the manager. *

* It is invoked by iPojo when an instance becomes INVALID. *

*/ public void stop() { this.logger.info( "The DM is about to be stopped." ); if( this.timer != null ) { this.timer.cancel(); this.timer = null; } if( this.messagingClient != null ) { // Stops listening to the debug queue. try { this.messagingClient.listenToTheDm( ListenerCommand.STOP ); } catch ( IOException e ) { this.logger.log( Level.WARNING, "Cannot stop to listen to the debug queue", e ); } this.messagingClient.getMessageProcessor().stopProcessor(); this.messagingClient.getMessageProcessor().interrupt(); try { this.messagingClient.closeConnection(); } catch( IOException e ) { this.logger.warning( "The messaging client could not be terminated correctly. " + e.getMessage()); Utils.logException( this.logger, e ); } } this.logger.info( "The DM was stopped." ); } /** * This method is invoked by iPojo every time a new target handler appears. * @param targetItf the appearing target handler */ public void targetAppears( TargetHandler targetItf ) { this.defaultTargetHandlerResolver.addTargetHandler( targetItf ); // When a target is deployed, we may also have to update instance states. // Consider as an example when the DM restarts. Targets may be injected // before and after the pojo was started by iPojo. // See #519 for more details. // Notice we restore instances only when the DM was started (the messaging // must be ready). If it is not started, do nothing. The "start" method // will trigger the restoration. // We consider the DM is started if the timer is not null. if( this.timer != null ) restoreInstancesFrom( targetItf ); } /** * This method is invoked by iPojo every time a target handler disappears. * @param targetItf the disappearing target handler */ public void targetDisappears( TargetHandler targetItf ) { this.defaultTargetHandlerResolver.removeTargetHandler( targetItf ); } /** * This method is invoked by iPojo every time a DM listener appears. * @param targetItf the appearing listener */ public void listenerAppears( IDmListener listener ) { this.notificationMngr.addListener( listener ); } /** * This method is invoked by iPojo every time a DM listener disappears. * @param listener the disappearing listener */ public void listenerDisappears( IDmListener listener ) { this.notificationMngr.removeListener( listener ); } // Reconfiguration /** * This method reconfigures the manager. *

* It is NOT invoked DIRECTLY by iPojo anymore. *

*/ public void reconfigure() { // Update the messaging client if( this.messagingClient != null ) { this.messagingClient.switchMessagingType( this.messagingType ); try { if( this.messagingClient.isConnected()) this.messagingClient.listenToTheDm( ListenerCommand.START ); } catch ( IOException e ) { this.logger.log( Level.WARNING, "Cannot start to listen to the debug queue", e ); } } // We must update instance states after we switched the messaging configuration. restoreAllInstances(); this.logger.info( "The DM was successfully (re)configured." ); } // Setters public void setMessagingType( String messagingType ) { // Properties are injected on every modification. // so, we just want to track changes. // We only want to reconfigure the messaging client // when the messaging type changes. if( ! Objects.equals( this.messagingType, messagingType )) { this.messagingType = messagingType; // Explicitly require a reconfiguration. reconfigure(); } } public void setTargetResolver( ITargetHandlerResolver targetHandlerResolver ) { if( targetHandlerResolver == null ) this.instancesMngr.setTargetHandlerResolver( this.defaultTargetHandlerResolver ); else this.instancesMngr.setTargetHandlerResolver( targetHandlerResolver ); } // Getters public INotificationMngr notificationMngr() { return this.notificationMngr; } public IMessagingMngr messagingMngr() { return this.messagingMngr; } public IApplicationMngr applicationMngr() { return this.applicationMngr; } public IInstancesMngr instancesMngr() { return this.instancesMngr; } public IConfigurationMngr configurationMngr() { return this.configurationMngr; } public IApplicationTemplateMngr applicationTemplateMngr() { return this.applicationTemplateMngr; } public ITargetsMngr targetsMngr() { return this.targetsMngr; } public IDebugMngr debugMngr() { return this.debugMngr; } public ICommandsMngr commandsMngr() { return this.commandsMngr; } public IPreferencesMngr preferencesMngr() { return this.preferencesMngr; } public IAutonomicMngr autonomicMngr() { return this.autonomicMngr; } // Private utilities /** * Restores the states of all the instances from the current target handlers. */ void restoreAllInstances() { // instancesMngr() instead of this.instancesMngr (for unit tests). this.logger.fine( "Restoring all the instance states from the current target handlers." ); for( ManagedApplication ma : this.applicationMngr.getManagedApplications()) { // Build a new snapshot on every loop List snapshot = this.defaultTargetHandlerResolver.getTargetHandlersSnapshot(); for( TargetHandler targetHandler : snapshot ) instancesMngr().restoreInstanceStates( ma, targetHandler ); } } /** * Restores the states of all the instances from a given target handler. */ void restoreInstancesFrom( TargetHandler targetHandler ) { // instancesMngr() instead of this.instancesMngr (for unit tests). this.logger.fine( "Restoring the instance states with the '" + targetHandler.getTargetId() + "' target handler." ); for( ManagedApplication ma : this.applicationMngr.getManagedApplications()) instancesMngr().restoreInstanceStates( ma, targetHandler ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy