/** * Inserts a child instance. * <p> * This method does not check anything. * In real implementations, such as in the DM, one should * use {@link #tryToInsertChildInstance(AbstractApplication, Instance, Instance)}. * </p> * * @param child a child instance (not null) * @param parent a parent instance (not null) */ public static void insertChild( Instance parent, Instance child ) { child.setParent( parent ); parent.getChildren().add( child ); }
/** * Removes children instances which are off-scope. * <p> * Agents manage all the instances under their scoped instance, except those * that are associated with the "target" installer. Such instances are indeed managed by another agent. * </p> * * @param scopedInstance a scoped instance */ public static void removeOffScopeInstances( Instance scopedInstance ) { List<Instance> todo = new ArrayList<> (); todo.addAll( scopedInstance.getChildren()); while( ! todo.isEmpty()) { Instance current = todo.remove( 0 ); if( isTarget( current )) current.getParent().getChildren().remove( current ); else todo.addAll( current.getChildren()); } }
/** * Finds all the scoped instances from an application. * @return a non-null list */ public static List<Instance> findAllScopedInstances( AbstractApplication app ) { List<Instance> instanceList = new ArrayList<> (); List<Instance> todo = new ArrayList<> (); todo.addAll( app.getRootInstances()); while( ! todo.isEmpty()) { Instance current = todo.remove( 0 ); todo.addAll( current.getChildren()); if( isTarget( current )) instanceList.add( current ); } return instanceList; }
/** * Determines whether an instance name is not already used by a sibling instance. * @param application the application (not null) * @param parentInstance the parent instance (can be null to indicate a root instance) * @param nameToSearch the name to search * @return true if a child instance of <code>parentInstance</code> has the same name, false otherwise */ public static boolean hasChildWithThisName( AbstractApplication application, Instance parentInstance, String nameToSearch ) { boolean hasAlreadyAChildWithThisName = false; Collection<Instance> list = parentInstance == null ? application.getRootInstances() : parentInstance.getChildren(); for( Iterator<Instance> it = list.iterator(); it.hasNext() && ! hasAlreadyAChildWithThisName; ) { hasAlreadyAChildWithThisName = Objects.equals( nameToSearch, it.next().getName()); } return hasAlreadyAChildWithThisName; }
Instance current = todo.remove( 0 ); instanceList.add( current ); todo.addAll( current.getChildren());
currentList = result.getChildren();
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." ); } }
insertChild( parent, copy ); toProcess.addAll( current.getChildren());
@Override public void stopAll( ManagedApplication ma, Instance instance ) throws IOException { this.messagingMngr.checkMessagingConfiguration(); Collection<Instance> initialInstances; if( instance != null ) initialInstances = Collections.singletonList(instance); else initialInstances = ma.getApplication().getRootInstances(); // We do not need to stop all the instances, just the first children. // Stop does not mean anything for targetsMngr. List<Exception> exceptions = new ArrayList<> (); for( Instance initialInstance : initialInstances ) { try { if( ! InstanceHelpers.isTarget( initialInstance )) changeInstanceState( ma, initialInstance, InstanceStatus.DEPLOYED_STOPPED ); else for( Instance i : initialInstance.getChildren()) changeInstanceState( ma, i, InstanceStatus.DEPLOYED_STOPPED ); } catch( Exception e ) { exceptions.add( e ); } } processExceptions( this.logger, exceptions, "One or several errors occurred while stopping instances." ); }
/** * Removes an instance to the local model. * @param msg the message to process * @throws IOException if an error occurred with the messaging */ void processMsgRemoveInstance( MsgCmdRemoveInstance msg ) throws IOException { // Remove the instance boolean removed = false; Instance instance = InstanceHelpers.findInstanceByPath( this.scopedInstance, msg.getInstancePath()); if( instance == null ) { this.logger.severe( "No instance matched " + msg.getInstancePath() + " on the agent. Request to remove it from the model is dropped." ); } else if( instance.getStatus() != InstanceStatus.NOT_DEPLOYED ) { this.logger.severe( "Instance " + msg.getInstancePath() + " cannot be removed. Instance status: " + instance.getStatus() + "." ); // We do not have to check children's status. // We cannot have a parent in NOT_DEPLOYED and a child in STARTED (as an example). } else if( instance.getParent() != null ) { removed = true; instance.getParent().getChildren().remove( instance ); this.logger.fine( "Child instance " + msg.getInstancePath() + " was removed from the model." ); } else { this.logger.fine( "The root instance " + msg.getInstancePath() + " cannot be removed. The agent must be reboot and/or reconfigured." ); } // Configure the messaging if( removed ) { this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceRemoved( this.agent.getApplicationName(), instance )); for( Instance instanceToProcess : InstanceHelpers.buildHierarchicalList( instance )) this.messagingClient.listenToExportsFromOtherAgents( ListenerCommand.STOP, instanceToProcess ); } }
@Test public void testInsertChild() { Instance instance_1 = new Instance( "inst 1" ); Instance instance_1_1 = new Instance( "inst 11" ); Assert.assertNull( instance_1.getParent()); Assert.assertNull( instance_1_1.getParent()); Assert.assertEquals( 0, instance_1.getChildren().size()); InstanceHelpers.insertChild( instance_1, instance_1_1 ); Assert.assertEquals( 1, instance_1.getChildren().size()); Assert.assertEquals( instance_1_1, instance_1.getChildren().iterator().next()); Assert.assertEquals( instance_1, instance_1_1.getParent()); Assert.assertTrue( instance_1.getChildren().contains( instance_1_1 )); Assert.assertNull( instance_1.getParent()); Assert.assertNotSame( instance_1, instance_1_1 ); }
Collection<ModelError> errors = RuntimeModelValidator.validate( allInstances ); if( RoboconfErrorHelpers.containsCriticalErrors( errors )) { parentInstance.getChildren().remove( childInstance ); childInstance.setParent( null );
@Test public void testComponentResolutionWhenSurroundingSpaces() throws Exception { Component vmComponent = new Component( "VM" ).installerName( "target" ); Component aComponent = new Component( "A" ).installerName( "whatever" ); vmComponent.addChild( aComponent ); Graphs graphs = new Graphs(); graphs.getRootComponents().add( vmComponent ); File f = TestUtils.findTestFile( "/configurations/valid/instance-with-space-after.instances" ); FromInstanceDefinition fromDef = new FromInstanceDefinition( f.getParentFile()); Collection<Instance> rootInstances = fromDef.buildInstances( graphs, f ); Iterator<ParsingError> iterator = fromDef.getErrors().iterator(); Assert.assertFalse( iterator.hasNext()); Assert.assertEquals( 2, rootInstances.size()); for( Instance rootInstance : rootInstances ) { Assert.assertEquals( 1, rootInstance.getChildren().size()); Instance instance = rootInstance.getChildren().iterator().next(); Assert.assertEquals( "A", instance.getComponent().getName()); Assert.assertEquals( "A ", instance.getName()); } }
instance.getParent().getChildren().remove( instance );
@Test public void testInstanceWithExtraData() throws Exception { Component vmComponent = new Component( "VM" ).installerName( "target" ); Component tomcatComponent = new Component( "Tomcat" ).installerName( "puppet" ); tomcatComponent.addExportedVariable( new ExportedVariable( "tomcat.ip", null )); tomcatComponent.addExportedVariable( new ExportedVariable( "tomcat.port", "8080" )); vmComponent.addChild( tomcatComponent ); Graphs graphs = new Graphs(); graphs.getRootComponents().add( vmComponent ); File f = TestUtils.findTestFile( "/configurations/valid/instance-with-extra-data.instances" ); FromInstanceDefinition fromDef = new FromInstanceDefinition( f.getParentFile()); Collection<Instance> rootInstances = fromDef.buildInstances( graphs, f ); Assert.assertEquals( 0, fromDef.getErrors().size()); Assert.assertEquals( 1, rootInstances.size()); Instance vmInstance = rootInstances.iterator().next(); Assert.assertEquals( 1, vmInstance.getChildren().size()); Assert.assertEquals( "VM1", vmInstance.getName()); Assert.assertEquals( 1, vmInstance.data.size()); Assert.assertEquals( "192.168.1.10", vmInstance.data.get( "ec2.elastic.ip" )); }
@Test public void testExtraData() throws Exception { // Parse Component vmComponent = new Component( "VM" ).installerName( "target" ); Component tomcatComponent = new Component( "Tomcat" ).installerName( "puppet" ); tomcatComponent.addExportedVariable( new ExportedVariable( "tomcat.ip", null )); tomcatComponent.addExportedVariable( new ExportedVariable( "tomcat.port", "8080" )); vmComponent.addChild( tomcatComponent ); Graphs graphs = new Graphs(); graphs.getRootComponents().add( vmComponent ); File f = TestUtils.findTestFile( "/configurations/valid/instance-with-extra-data.instances" ); FromInstanceDefinition fromDef = new FromInstanceDefinition( f.getParentFile()); Collection<Instance> rootInstances = fromDef.buildInstances( graphs, f ); Assert.assertEquals( 0, fromDef.getErrors().size()); Assert.assertEquals( 1, rootInstances.size()); Instance vmInstance = rootInstances.iterator().next(); Assert.assertEquals( 1, vmInstance.getChildren().size()); Assert.assertEquals( "VM1", vmInstance.getName()); Assert.assertEquals( 1, vmInstance.data.size()); Assert.assertEquals( "192.168.1.10", vmInstance.data.get( "ec2.elastic.ip" )); // Write compareInstances( graphs, Arrays.asList( vmInstance ), true, true ); }
@Test public void checkInstanceReplication() { TestApplicationTemplate tpl = new TestApplicationTemplate(); Application app = new Application( tpl ); Assert.assertEquals( 5, InstanceHelpers.getAllInstances( app ).size()); Assert.assertEquals( 5, InstanceHelpers.getAllInstances( tpl ).size()); for( Instance inst : InstanceHelpers.getAllInstances( tpl )) { String instancePath = InstanceHelpers.computeInstancePath( inst ); Instance copiedInstance = InstanceHelpers.findInstanceByPath( app, instancePath ); Assert.assertNotNull( copiedInstance ); Assert.assertEquals( inst.getName(), copiedInstance.getName()); Assert.assertEquals( inst.getComponent(), copiedInstance.getComponent()); Assert.assertEquals( inst.getImports(), copiedInstance.getImports()); Assert.assertEquals( inst.getParent(), copiedInstance.getParent()); Assert.assertEquals( inst.getChildren().size(), copiedInstance.getChildren().size()); // Paths are the same, so the children are equal (even if they are not the same object) Assert.assertEquals( inst.getChildren(), copiedInstance.getChildren()); Assert.assertEquals( inst.channels, copiedInstance.channels ); Assert.assertEquals( inst.overriddenExports, copiedInstance.overriddenExports ); Assert.assertEquals( inst.data, copiedInstance.data ); Assert.assertFalse( inst == copiedInstance ); } }
vmInstance1.getChildren().clear(); InstanceHelpers.insertChild( vmInstance1, tomcatInstance ); app.getRootInstances().clear();
Assert.assertEquals( instance.getComponent(), newInstance.getComponent()); Assert.assertEquals( instance.getStatus(), newInstance.getStatus()); Assert.assertEquals( instance.getChildren().size(), newInstance.getChildren().size()); Assert.assertEquals( instance.data, newInstance.data ); Assert.assertEquals( instance.overriddenExports.size(), newInstance.overriddenExports.size());
@Test public void testComputeInstancePath() { Instance instance1 = new Instance(); Assert.assertEquals( "/", InstanceHelpers.computeInstancePath( instance1 )); instance1.setName( "inst1" ); Assert.assertEquals( "/inst1", InstanceHelpers.computeInstancePath( instance1 )); Instance instance2 = new Instance( "inst2" ); Assert.assertEquals( "/inst2", InstanceHelpers.computeInstancePath( instance2 )); instance1.getChildren().add( instance2 ); instance2.setParent( instance1 ); Assert.assertEquals( "/inst1", InstanceHelpers.computeInstancePath( instance1 )); Assert.assertEquals( "/inst1/inst2", InstanceHelpers.computeInstancePath( instance2 )); }