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

net.roboconf.dm.internal.environment.messaging.DmMessageProcessor 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.internal.environment.messaging;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;

import net.roboconf.core.model.beans.Application;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.ImportHelpers;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.DockerAndScriptUtils;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.management.ManagedApplication;
import net.roboconf.dm.management.Manager;
import net.roboconf.dm.management.api.IAutonomicMngr;
import net.roboconf.messaging.api.AbstractMessageProcessor;
import net.roboconf.messaging.api.business.IDmClient;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifAutonomic;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifHeartbeat;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifInstanceChanged;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifInstanceRemoved;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifLogs;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifMachineDown;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdSetScopedInstance;
import net.roboconf.messaging.api.messages.from_dm_to_dm.MsgEcho;

/**
 * This class is in charge of updating the model from messages / notifications.
 * 

* These messages have been sent by an agent. *

* * @author Noël - LIG * @author Pierre Bourret - Université Joseph Fourier */ public class DmMessageProcessor extends AbstractMessageProcessor { private final Logger logger = Logger.getLogger( DmMessageProcessor.class.getName()); private final Manager manager; private final IAutonomicMngr autonomicMngr; // Set as a class attribute so that it can be replaced for unit tests. String tmpDir = System.getProperty( "java.io.tmpdir" ); /** * Constructor. * @param manager */ public DmMessageProcessor( Manager manager ) { super( "Roboconf DM - Message Processor" ); this.manager = manager; this.autonomicMngr = manager.autonomicMngr(); } /* * (non-Javadoc) * @see net.roboconf.messaging.api.business.AbstractMessageProcessor * #processMessage(net.roboconf.messaging.api.messages.Message) */ @Override public void processMessage( Message message ) { if( message instanceof MsgNotifMachineDown ) processMsgNotifMachineDown((MsgNotifMachineDown) message ); else if( message instanceof MsgNotifInstanceChanged ) processMsgNotifInstanceChanged((MsgNotifInstanceChanged) message ); else if( message instanceof MsgNotifInstanceRemoved ) processMsgNotifInstanceRemoved((MsgNotifInstanceRemoved) message ); else if( message instanceof MsgNotifHeartbeat ) processMsgNotifHeartbeat((MsgNotifHeartbeat) message ); else if(message instanceof MsgNotifAutonomic) processMsgMonitoringEvent((MsgNotifAutonomic) message ); else if( message instanceof MsgEcho ) this.manager.debugMngr().notifyMsgEchoReceived((MsgEcho) message ); else if( message instanceof MsgNotifLogs ) processMsgNotifLogs((MsgNotifLogs) message ); else this.logger.warning( "The DM got an undetermined message to process: " + message.getClass().getName()); } private void processMsgNotifLogs( MsgNotifLogs message ) { StringBuilder path = new StringBuilder(); path.append( "roboconf-logs/" ); path.append( message.getApplicationName()); path.append( "/" ); path.append( DockerAndScriptUtils.cleanInstancePath( message.getScopedInstancePath())); // Dump these messages in the temporary directory... File dumpDir = new File( this.tmpDir, path.toString()); try { Utils.createDirectory( dumpDir ); for( Map.Entry entry : message.getLogFiles().entrySet()) { ByteArrayInputStream in = new ByteArrayInputStream( entry.getValue()); Utils.copyStream( in, new File( dumpDir, entry.getKey())); } } catch( IOException e ) { StringBuilder sb = new StringBuilder(); sb.append( "An error occurred while dumping logs from agent " ); sb.append( message.getScopedInstancePath()); sb.append( " @ " ); sb.append( message.getApplicationName()); sb.append( ". " ); if( ! Utils.isEmptyOrWhitespaces( e.getMessage())) sb.append( e.getMessage()); this.logger.severe( sb.toString()); Utils.logException( this.logger, e ); } } private void processMsgNotifMachineDown( MsgNotifMachineDown message ) { String scopedInstancePath = message.getScopedInstancePath(); Application app = this.manager.applicationMngr().findApplicationByName( message.getApplicationName()); Instance scopedInstance = InstanceHelpers.findInstanceByPath( app, scopedInstancePath ); // If 'app' is null, then 'instance' is also null. if( scopedInstance == null ) { StringBuilder sb = new StringBuilder(); sb.append( "A 'DOWN' notification was received from an unknown agent: " ); sb.append( scopedInstancePath ); sb.append( " (app = " ); sb.append( app ); sb.append( ")." ); this.logger.warning( sb.toString()); } else { scopedInstance.data.remove( Instance.IP_ADDRESS ); scopedInstance.data.remove( Instance.TARGET_ACQUIRED ); scopedInstance.data.remove( Instance.RUNNING_FROM ); scopedInstance.data.remove( Instance.MACHINE_ID ); for( Instance inst : InstanceHelpers.buildHierarchicalList( scopedInstance )) { inst.setStatus( InstanceStatus.NOT_DEPLOYED ); } this.logger.info( scopedInstance + " is now terminated. Back to NOT_DEPLOYED state." ); } } private void processMsgNotifHeartbeat( MsgNotifHeartbeat message ) { String scopedInstancePath = message.getScopedInstancePath(); ManagedApplication ma = this.manager.applicationMngr().findManagedApplicationByName( message.getApplicationName()); Application app = ma == null ? null : ma.getApplication(); Instance scopedInstance = InstanceHelpers.findInstanceByPath( app, scopedInstancePath ); if( scopedInstance == null ) { // If 'app' is null, then 'instance' is also null. StringBuilder sb = new StringBuilder(); sb.append( "A 'HEART BEAT' was received from an unknown agent: " ); sb.append( scopedInstancePath ); sb.append( " (app = " ); sb.append( ma ); sb.append( ", inst = " ); sb.append( scopedInstancePath ); sb.append( "). The heart beat is dropped." ); this.logger.warning( sb.toString()); } else if( ! InstanceHelpers.isTarget( scopedInstance )) { StringBuilder sb = new StringBuilder(); sb.append( "A 'HEART BEAT' was received for a non-scoped instance: " ); sb.append( scopedInstancePath ); sb.append( " (app = " ); sb.append( ma ); sb.append( ", inst = " ); sb.append( scopedInstancePath ); sb.append( "). The heart beat is dropped." ); this.logger.warning( sb.toString()); } else { // Update the data String ipAddress = message.getIpAddress(); if( scopedInstance.data.get( Instance.IP_ADDRESS ) == null ) { this.logger.fine( scopedInstancePath + " @ " + ipAddress + " is up and running." ); scopedInstance.data.put( Instance.IP_ADDRESS, ipAddress ); this.manager.instancesMngr().instanceWasUpdated( scopedInstance, ma ); } ma.acknowledgeHeartBeat( scopedInstance ); this.logger.finest( "A heart beat was acknowledged for " + scopedInstancePath + " in the application " + ma + "." ); try { // A heart beat may also say whether the agent receive its model if( message.isModelRequired()) { this.logger.fine( "The DM is sending its model to agent " + scopedInstancePath + "." ); Message msg = new MsgCmdSetScopedInstance( scopedInstance, app.getExternalExports(), app.applicationBindings ); this.messagingClient.sendMessageToAgent( ma.getApplication(), scopedInstance, msg ); } // Send stored messages after an acknowledgement this.manager.messagingMngr().sendStoredMessages( ma, scopedInstance ); } catch( IOException e ) { this.logger.warning( "Agent " + scopedInstancePath + " requested its model but an error occurred. " + e.getMessage()); Utils.logException( this.logger, e ); } } } private void processMsgNotifInstanceChanged( MsgNotifInstanceChanged message ) { String instancePath = message.getInstancePath(); ManagedApplication ma = this.manager.applicationMngr().findManagedApplicationByName( message.getApplicationName()); Application app = ma == null ? null : ma.getApplication(); Instance instance = InstanceHelpers.findInstanceByPath( app, instancePath ); // If 'app' is null, then 'instance' is also null. if( instance == null ) { StringBuilder sb = new StringBuilder(); sb.append( "A 'CHANGED' notification was received from an unknown instance: " ); sb.append( instancePath ); sb.append( " (app = " ); sb.append( app ); sb.append( ")." ); this.logger.warning( sb.toString()); } else if( InstanceHelpers.findRootInstance( instance ).getStatus() == InstanceStatus.NOT_DEPLOYED ) { // See roboconf-platform #107 StringBuilder sb = new StringBuilder(); sb.append( "A 'CHANGED' notification was received from a instance: " ); sb.append( instancePath ); sb.append( " (app = " ); sb.append( app ); sb.append( ") but the root instance is not deployed. Status update is dismissed." ); this.logger.warning( sb.toString()); } else { InstanceStatus oldStatus = instance.getStatus(); instance.setStatus( message.getNewStatus()); ImportHelpers.updateImports( instance, message.getNewImports()); StringBuilder sb = new StringBuilder(); sb.append( "Status changed from " ); sb.append( oldStatus ); sb.append( " to " ); sb.append( message.getNewStatus() ); sb.append( " for instance " ); sb.append( instancePath ); sb.append( ". Imports were updated too." ); this.logger.fine( sb.toString()); // Notify the changes! this.manager.instancesMngr().instanceWasUpdated( instance, ma ); } } private void processMsgNotifInstanceRemoved( MsgNotifInstanceRemoved message ) { String instancePath = message.getInstancePath(); Application app = this.manager.applicationMngr().findApplicationByName( message.getApplicationName()); Instance instance = InstanceHelpers.findInstanceByPath( app, instancePath ); // If 'app' is null, then 'instance' is also null. if( instance == null ) { StringBuilder sb = new StringBuilder(); sb.append( "A 'REMOVE' notification was received for an unknown instance: " ); sb.append( instancePath ); sb.append( " (app = " ); sb.append( app ); sb.append( ")." ); this.logger.warning( sb.toString()); } else { if( InstanceHelpers.isTarget( instance )) this.logger.warning( "Anormal behavior. A 'REMOVE' notification was received for a scoped instance: " + instancePath + "." ); else instance.getParent().getChildren().remove( instance ); this.logger.info( "Instance " + instancePath + " was removed from the model." ); } } private void processMsgMonitoringEvent( MsgNotifAutonomic message ) { Application app = this.manager.applicationMngr().findApplicationByName( message.getApplicationName()); Instance scopedInstance = InstanceHelpers.findInstanceByPath( app, message.getScopedInstancePath()); // If 'app' is null, then 'instance' is also null. if( scopedInstance == null ) { StringBuilder sb = new StringBuilder(); sb.append( "A notification associated with autonomic management was received for an unknown instance: " ); sb.append( message.getScopedInstancePath()); sb.append( " (app = " ); sb.append( app ); sb.append( ")." ); this.logger.warning( sb.toString()); } else { ManagedApplication ma = this.manager.applicationMngr().findManagedApplicationByName( app.getName()); this.autonomicMngr.handleEvent( ma, message ); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy