public String getName() { return this.application.getName(); }
@Override public void unloadApplicationRules( Application app ) { this.appNameToContext.remove( app.getName()); }
@Override public boolean equals( Object obj ) { return obj instanceof Application && Objects.equals( this.name, ((Application) obj ).getName()); }
@Override public void refreshApplicationRules( Application app, String ruleFileName ) { AutonomicApplicationContext ctx = this.appNameToContext.get( app.getName()); if( ctx != null ) loadRule( app, ctx, ruleFileName ); }
/** * Details for an application. * @param app the application * @return an object with error details */ public static ErrorDetails application( Application app ) { return new ErrorDetails( app.getName(), ErrorDetailsKind.APPLICATION ); }
@Override public void deleteMessagingServerArtifacts( Application application ) throws IOException { // We delete the application exchanges. There is only one now. // The DM and inter-applications stuff have each one a single exchange, shared by all the applications. this.channel.exchangeDelete( RabbitMqUtils.buildExchangeNameForAgent( this.domain, application.getName())); this.logger.fine( "Messaging artifacts were deleted for application " + application ); // Queues are deleted automatically by RabbitMQ. }
@Override public void releaseAllRandomValues( Application application ) { // Only used for random ports. // Find the contexts to remove List<InstanceContext> toRemove = new ArrayList<> (); for( InstanceContext ctx : this.agentToRandomPorts.keySet()) { if( ctx.getQualifier() == null && Objects.equals( application.getName(), ctx.getName())) toRemove.add( ctx ); } // Remove them for( InstanceContext ctx : toRemove ) this.agentToRandomPorts.remove( ctx ); }
@Override public void loadApplicationRules( Application app ) { // Create the context AutonomicApplicationContext ctx = new AutonomicApplicationContext( app ); // Load the rule loadRule( app, ctx, null ); // Register the context this.appNameToContext.put( app.getName(), ctx ); }
protected void listenToAgentMessages( IMessagingClient messagingClient, Application application, ListenerCommand command ) throws IOException { // The context match the one used by agents to send messages to the DM. MessagingContext ctx = new MessagingContext( RecipientKind.DM, this.domain, application.getName()); if( command == ListenerCommand.STOP ) messagingClient.unsubscribe( ctx ); else messagingClient.subscribe( ctx ); } }
protected void listenToAgentMessages( IMessagingClient messagingClient, Application application, ListenerCommand command ) throws IOException { // The context match the one used by agents to send messages to the DM. MessagingContext ctx = new MessagingContext( RecipientKind.DM, this.domain, application.getName()); if( command == ListenerCommand.STOP ) messagingClient.unsubscribe( ctx ); else messagingClient.subscribe( ctx ); } }
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.manager.autonomicMngr().handleEvent( ma, message ); } } }
/** * Restores instances and set them in the application. * @param ma the application * @param configurationDirectory the configuration directory */ public static InstancesLoadResult restoreInstances( ManagedApplication ma ) { File sourceFile = new File( ma.getDirectory(), Constants.PROJECT_DIR_INSTANCES + "/" + INSTANCES_FILE ); Graphs graphs = ma.getApplication().getTemplate().getGraphs(); InstancesLoadResult result; if( sourceFile.exists()) result = RuntimeModelIo.loadInstances( sourceFile, sourceFile.getParentFile(), graphs, ma.getApplication().getName()); else result = new InstancesLoadResult(); return result; }
@Override public void application( Application application, EventType eventType ) { if( eventType == EventType.DELETED ) { this.logger.fine( "Application " + application + " was deleted. Associated jobs are about to be deleted." ); try { Set<TriggerKey> tks = this.scheduler.scheduler.getTriggerKeys( GroupMatcher.triggerGroupEquals( application.getName())); for( TriggerKey tk : tks ) { try { this.scheduler.deleteJob( tk.getName()); } catch( Exception e ) { this.logger.warning( "An error occurred while unscheduling job " + tk.getName() + ". " + e.getMessage()); Utils.logException( this.logger, e ); } } } catch( Exception e ) { this.logger.warning( "An error occurred while listing jobs for application " + application + ". " + e.getMessage()); Utils.logException( this.logger, e ); } } } }
@Override public void sendMessageToAgent( Application application, Instance instance, Message message ) throws IOException { // The context match the one used by agents to listen to messages sent by the DM. String topicName = MessagingUtils.buildTopicNameForAgent( instance ); MessagingContext ctx = new MessagingContext( RecipientKind.AGENTS, this.domain, topicName, application.getName()); getMessagingClient().publish( ctx, message ); }
@Override public void propagateAgentTermination( Application application, Instance rootInstance ) throws IOException { // Start with the deepest instances List<Instance> instances = InstanceHelpers.buildHierarchicalList( rootInstance ); Collections.reverse( instances ); // Roughly, we unpublish all the variables for all the instances that were on the agent's machine. // This code is VERY similar to ...ClientAgent#unpublishExports // The messages will go through JUST like if they were coming from other agents. this.logger.fine( "The DM is un-publishing exports related to agent of " + rootInstance + " (termination propagation)." ); for( Instance instance : instances ) { for( MessagingContext ctx : MessagingContext.forExportedVariables( this.domain, application.getName(), instance, application.getExternalExports(), ThoseThat.IMPORT )) { MsgCmdRemoveImport message = new MsgCmdRemoveImport( application.getName(), ctx.getComponentOrFacetName(), InstanceHelpers.computeInstancePath( instance )); // FIXME: external exports are not handled here!!!! getMessagingClient().publish( ctx, message ); } } }
@Override public void sendMessageToAgent( Application application, Instance instance, Message message ) throws IOException { // The context match the one used by agents to listen to messages sent by the DM. String topicName = MessagingUtils.buildTopicNameForAgent( instance ); MessagingContext ctx = new MessagingContext( RecipientKind.AGENTS, this.domain, topicName, application.getName()); getMessagingClient().publish( ctx, message ); }
@Override public void updateApplication( ManagedApplication ma, String newDesc ) throws IOException { // Basic checks this.messagingMngr.checkMessagingConfiguration(); // Update it Application app = ma.getApplication(); app.setDescription( newDesc ); File targetDirectory = app.getDirectory(); File descFile = new File( targetDirectory, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ); Utils.createDirectory( descFile.getParentFile()); ApplicationDescriptor.save( descFile, app ); // Notify listeners this.notificationMngr.application( ma.getApplication(), EventType.CHANGED ); this.logger.fine( "The description of application " + ma.getApplication().getName() + " was successfully updated." ); }
@Test public void testSetNameWithAccents() { Application app = new Application( "avé dés àcçents", new TestApplicationTemplate()); Assert.assertEquals( "ave des accents", app.getName()); Assert.assertEquals( "avé dés àcçents", app.getDisplayName()); app.setName( " " ); Assert.assertEquals( "", app.getName()); Assert.assertEquals( "", app.getDisplayName()); app.setName( null ); Assert.assertNull( app.getName()); Assert.assertNull( app.getDisplayName()); app.setName( " âêû éèà " ); Assert.assertEquals( "aeu eea", app.getName()); Assert.assertEquals( "âêû éèà", app.getDisplayName()); } }
@Override public ManagedApplication createApplication( String name, String description, ApplicationTemplate tpl ) throws IOException, AlreadyExistingException { // Always verify the configuration first this.messagingMngr.checkMessagingConfiguration(); // Create the application ManagedApplication ma = createNewApplication( name, description, tpl, this.configurationMngr.getWorkingDirectory()); // Copy the target settings, if any this.targetsMngr.copyOriginalMapping( ma.getApplication()); // Set a value to random variables, if any this.randomMngr.generateAllRandomValues( ma.getApplication()); // Start listening to messages this.messagingMngr.getMessagingClient().listenToAgentMessages( ma.getApplication(), ListenerCommand.START ); // Notify listeners this.notificationMngr.application( ma.getApplication(), EventType.CREATED ); // Load autonomic rules this.autonomicMngr.loadApplicationRules( ma.getApplication()); this.logger.fine( "Application " + ma.getApplication().getName() + " was successfully loaded and added." ); return ma; }
@Test public void testChain() { Application app = new Application( new ApplicationTemplate()).name( "ins" ).description( "desc" ); Assert.assertEquals( "ins", app.getName()); Assert.assertEquals( "desc", app.getDescription()); }