/**
* Copyright 2014-2017 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.agent.internal;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import net.roboconf.agent.internal.misc.PluginMock;
import net.roboconf.agent.internal.test.AgentTestUtils;
import net.roboconf.core.Constants;
import net.roboconf.core.internal.tests.TestApplicationTemplate;
import net.roboconf.core.model.beans.Component;
import net.roboconf.core.model.beans.ImportedVariable;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.Utils;
import net.roboconf.messaging.api.MessagingConstants;
import net.roboconf.messaging.api.factory.MessagingClientFactoryRegistry;
import net.roboconf.messaging.api.internal.client.test.TestClient;
import net.roboconf.messaging.api.internal.client.test.TestClientFactory;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_agent_to_agent.MsgCmdAddImport;
import net.roboconf.messaging.api.messages.from_agent_to_agent.MsgCmdRemoveImport;
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_dm_to_agent.MsgCmdAddInstance;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdChangeBinding;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdRemoveInstance;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdResynchronize;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdSendInstances;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdSetScopedInstance;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdUpdateProbeConfiguration;
import net.roboconf.messaging.api.messages.from_dm_to_dm.MsgEcho;
/**
* @author Vincent Zurczak - Linagora
*/
public class AgentMessageProcessorBasicTest {
private Agent agent;
private TestClient client;
@Before
public void initializeAgent() throws Exception {
final MessagingClientFactoryRegistry registry = new MessagingClientFactoryRegistry();
registry.addMessagingClientFactory(new TestClientFactory());
this.agent = new Agent();
// We first need to start the agent, so it creates the reconfigurable messaging client.
this.agent.setMessagingType(MessagingConstants.FACTORY_TEST);
this.agent.start();
// We then set the factory registry of the created client, and reconfigure the agent, so the messaging client backend is created.
this.agent.getMessagingClient().setRegistry(registry);
this.agent.reconfigure();
Thread.sleep( 200 );
this.client = AgentTestUtils.getInternalClient( this.agent.getMessagingClient());
this.client.clearMessages();
}
@After
public void stopAgent() {
this.agent.stop();
}
@Test
public void testDmPingResponse() throws IllegalAccessException {
// Simulate a ping message from the DM.
MsgEcho ping = new MsgEcho( "PING:TEST" );
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
processor.processMessage( ping );
// Check the agent has sent a 'PONG' response to the DM.
List<Message> messages = this.client.messagesForTheDm;
Assert.assertEquals( 1, messages.size());
Message message = messages.get(0);
Assert.assertTrue( message instanceof MsgEcho );
MsgEcho echo = (MsgEcho) message;
Assert.assertEquals( "PONG:TEST", echo.getContent());
Assert.assertEquals( ping.getUuid(), echo.getUuid());
}
@Test
public void testAddInstance() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
// Adding an child instance when there is no root
Assert.assertNull( processor.scopedInstance );
processor.processMessage( new MsgCmdAddInstance( app.getMySql()));
Assert.assertNull( processor.scopedInstance );
// Adding a root instance must fail too
processor.processMessage( new MsgCmdAddInstance( app.getMySqlVm()));
Assert.assertNull( processor.scopedInstance );
// Create a copy of the root instance and insert a child
Instance newMySqlVm = new Instance( app.getMySqlVm().getName()).component( app.getMySqlVm().getComponent());
processor.scopedInstance = newMySqlVm;
app.getMySql().overriddenExports.put( "some-value", "loop" );
Assert.assertEquals( 0, newMySqlVm.getChildren().size());
processor.processMessage( new MsgCmdAddInstance( app.getMySql()));
Assert.assertEquals( 1, newMySqlVm.getChildren().size());
Instance newChild = newMySqlVm.getChildren().iterator().next();
Assert.assertEquals( app.getMySql(), newChild );
Assert.assertEquals( 1, newChild.overriddenExports.size());
Assert.assertEquals( "loop", newChild.overriddenExports.get( "some-value" ));
// Inserting an existing child fails
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( newMySqlVm ).size());
MsgCmdAddInstance msg = new MsgCmdAddInstance( app.getMySql());
msg.setData( null );
msg.setOverridenExports( null );
processor.processMessage( msg );
Assert.assertEquals( 1, newMySqlVm.getChildren().size());
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( newMySqlVm ).size());
// Same thing with a root instance
processor.processMessage( new MsgCmdAddInstance( app.getMySqlVm()));
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( newMySqlVm ).size());
// Try to insert an instance whose component is not in the graph
Instance inst = new Instance( "inst" ).component( new Component( "unknown" ));
InstanceHelpers.insertChild( app.getMySqlVm(), inst );
processor.processMessage( new MsgCmdAddInstance( inst ));
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( newMySqlVm ).size());
}
@Test
public void testSetScopedInstance() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
// Insert a non-root element
Assert.assertNull( processor.scopedInstance );
processor.processMessage( new MsgCmdSetScopedInstance( app.getMySql()));
Assert.assertNull( processor.scopedInstance );
Assert.assertEquals( 0, this.client.messagesForAgents.size());
// Insert a root
processor.processMessage( new MsgCmdSetScopedInstance( app.getTomcatVm()));
Assert.assertEquals( app.getTomcatVm(), processor.scopedInstance );
Assert.assertEquals( InstanceStatus.DEPLOYED_STARTED, processor.scopedInstance.getStatus());
// Only the WAR imports variables.
Assert.assertEquals( 1, this.client.messagesForAgents.size());
// We cannot change the root
processor.processMessage( new MsgCmdSetScopedInstance( app.getMySqlVm()));
Assert.assertEquals( app.getTomcatVm(), processor.scopedInstance );
processor.processMessage( new MsgCmdSetScopedInstance( app.getTomcat()));
Assert.assertEquals( app.getTomcatVm(), processor.scopedInstance );
// Make sure the final state of the root instance is always "deployed and started"
processor.scopedInstance = null;
this.client.messagesForAgents.clear();
app.getTomcatVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
processor.processMessage( new MsgCmdSetScopedInstance( app.getTomcatVm()));
Assert.assertEquals( app.getTomcatVm(), processor.scopedInstance );
Assert.assertEquals( InstanceStatus.DEPLOYED_STARTED, processor.scopedInstance.getStatus());
// Only the WAR imports variables.
Assert.assertEquals( "Expected a message for Tomcat, its VM and the WAR.", 1, this.client.messagesForAgents.size());
}
@Test
public void testSetscopedInstance_withAppBindings_andExternalExports() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
Map<String,String> externalExports = new HashMap<> ();
externalExports.put( "Lamp", "Toto" );
Map<String,Set<String>> applicationBindings = new HashMap<> ();
applicationBindings.put( "Tpl1", new HashSet<>( Arrays.asList( "app1", "app3" )));
applicationBindings.put( "Tpl2", new HashSet<>( Arrays.asList( "app2" )));
Map<String,byte[]> scriptResources = new HashMap<> ();
Message msg = new MsgCmdSetScopedInstance( app.getMySqlVm(), externalExports, applicationBindings, scriptResources );
// Send the message
Assert.assertNull( processor.scopedInstance );
Assert.assertEquals( 0, processor.applicationBindings.size());
processor.processMessage( msg );
Assert.assertEquals( app.getMySqlVm(), processor.scopedInstance );
Assert.assertEquals( 2, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "app2" )), processor.applicationBindings.get( "Tpl2" ));
Assert.assertEquals( new HashSet<>( Arrays.asList( "app1", "app3" )), processor.applicationBindings.get( "Tpl1" ));
}
@Test
public void testSetscopedInstance_nonRoot() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
app.getTomcat().getComponent().installerName( Constants.TARGET_INSTALLER );
// Insert a non-root element
Assert.assertNull( processor.scopedInstance );
processor.processMessage( new MsgCmdSetScopedInstance( app.getTomcat()));
Assert.assertEquals( app.getTomcat(), processor.scopedInstance );
Assert.assertEquals( InstanceStatus.DEPLOYED_STARTED, processor.scopedInstance.getStatus());
// Only the WAR imports variables.
Assert.assertEquals( "Expected a message for Tomcat and the WAR.", 1, this.client.messagesForAgents.size());
}
@Test
public void testSetscopedInstance_rootWithTargetChild() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
app.getTomcat().getComponent().installerName( Constants.TARGET_INSTALLER );
// Insert a root element
Assert.assertNull( processor.scopedInstance );
processor.processMessage( new MsgCmdSetScopedInstance( app.getTomcatVm()));
Assert.assertEquals( app.getTomcatVm(), processor.scopedInstance );
Assert.assertEquals( InstanceStatus.DEPLOYED_STARTED, processor.scopedInstance.getStatus());
// The VM is the only kept instance.
// And it does not export anything, so no sent message.
Assert.assertEquals( "Expected a message for the Tomcat VM (children were removed).", 0, this.client.messagesForAgents.size());
// The Tomcat (child) instance was removed because it is a target (so managed by another agent)
Assert.assertEquals( 1, InstanceHelpers.buildHierarchicalList( app.getTomcatVm()).size());
}
@Test
public void testSendInstances() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
// No root instance
processor.processMessage( new MsgCmdSendInstances());
Assert.assertEquals( 0, this.client.messagesForTheDm.size());
// With a root instance
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
processor.processMessage( new MsgCmdSendInstances());
Assert.assertEquals(
InstanceHelpers.buildHierarchicalList( app.getTomcatVm()).size(),
this.client.messagesForTheDm.size());
for( int i=1; i<3; i++ )
Assert.assertEquals( "Index " + i, MsgNotifInstanceChanged.class, this.client.messagesForTheDm.get( i ).getClass());
}
@Test
public void testResynchronize() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
// No root instance
processor.processMessage( new MsgCmdResynchronize());
Assert.assertEquals( 0, this.client.messagesForTheDm.size());
Assert.assertEquals( 0, this.client.messagesForAgents.size());
// With a root instance which has no variable.
// Unlike with a real messaging client, we do not check variables in our test client.
// So, one processed instance = one message sent other agents.
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
processor.scopedInstance.setStatus( InstanceStatus.DEPLOYED_STARTED );
// The VM is the only started component, and it does not export any variable.
processor.processMessage( new MsgCmdResynchronize());
Assert.assertEquals( 0, this.client.messagesForTheDm.size());
Assert.assertEquals( 0, this.client.messagesForAgents.size());
// Same thing with the Tomcat instance.
app.getTomcat().setStatus( InstanceStatus.DEPLOYED_STARTED );
processor.processMessage( new MsgCmdResynchronize());
Assert.assertEquals( 0, this.client.messagesForTheDm.size());
Assert.assertEquals( 0, this.client.messagesForAgents.size());
// Only the WAR imports variables.
app.getWar().setStatus( InstanceStatus.DEPLOYED_STARTED );
processor.processMessage( new MsgCmdResynchronize());
Assert.assertEquals( 0, this.client.messagesForTheDm.size());
Assert.assertEquals( 1, this.client.messagesForAgents.size());
}
@Test
public void testRemoveInstance() {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
// Remove an instance when there is no model
TestApplicationTemplate app = new TestApplicationTemplate();
Assert.assertNull( processor.scopedInstance );
processor.processMessage( new MsgCmdRemoveInstance( app.getMySqlVm()));
Assert.assertNull( processor.scopedInstance );
// Set a root instance and try to remove it => fail
processor.scopedInstance = app.getMySqlVm();
processor.processMessage( new MsgCmdRemoveInstance( app.getMySqlVm()));
Assert.assertEquals( app.getMySqlVm(), processor.scopedInstance );
// Try to remove an invalid child
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( app.getMySqlVm()).size());
processor.processMessage( new MsgCmdRemoveInstance( app.getTomcat()));
processor.processMessage( new MsgCmdRemoveInstance( app.getTomcatVm()));
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( app.getMySqlVm()).size());
// Try to remove a valid child (started) => fail
app.getMySql().setStatus( InstanceStatus.DEPLOYED_STARTED );
processor.processMessage( new MsgCmdRemoveInstance( app.getMySql()));
Assert.assertEquals( 2, InstanceHelpers.buildHierarchicalList( app.getMySqlVm()).size());
// Try to remove a valid child (not deployed) => OK
app.getMySql().setStatus( InstanceStatus.NOT_DEPLOYED );
processor.processMessage( new MsgCmdRemoveInstance( app.getMySql()));
Assert.assertEquals( 1, InstanceHelpers.buildHierarchicalList( app.getMySqlVm()).size());
Assert.assertEquals( 1, this.client.messagesForTheDm.size());
Assert.assertEquals( MsgNotifInstanceRemoved.class, this.client.messagesForTheDm.get( 0 ).getClass());
Assert.assertEquals(
InstanceHelpers.computeInstancePath( app.getMySql()),
((MsgNotifInstanceRemoved) this.client.messagesForTheDm.get( 0 )).getInstancePath());
}
@Test
public void testUpdateProbeConfiguration_instanceNotFound() throws Exception {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
processor.scopedInstance.setStatus( InstanceStatus.DEPLOYED_STARTED );
// Make sure no resource was saved
File dir = InstanceHelpers.findInstanceDirectoryOnAgent( app.getTomcatVm());
Utils.deleteFilesRecursively( dir );
Assert.assertFalse( dir.exists());
try {
// The VM is the only started component, and it does not export any variable.
Map<String,byte[]> map = new HashMap<>( 1 );
map.put( "VM.properties", new byte[ 0 ]);
MsgCmdUpdateProbeConfiguration msg = new MsgCmdUpdateProbeConfiguration( "/invalid", map );
processor.processMessage( msg );
Assert.assertFalse( dir.exists());
} finally {
Utils.deleteFilesRecursively( dir );
}
}
@Test
public void testUpdateProbeConfiguration_withValidInstance() throws Exception {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
processor.scopedInstance.setStatus( InstanceStatus.DEPLOYED_STARTED );
// Make sure no resource was saved
File dir = InstanceHelpers.findInstanceDirectoryOnAgent( app.getTomcatVm());
Utils.deleteFilesRecursively( dir );
Assert.assertFalse( dir.exists());
try {
// The VM is the only started component, and it does not export any variable.
Map<String,byte[]> map = new HashMap<>( 1 );
map.put( "VM.properties", new byte[ 0 ]);
MsgCmdUpdateProbeConfiguration msg = new MsgCmdUpdateProbeConfiguration( "/" + app.getTomcatVm(), map );
processor.processMessage( msg );
Assert.assertTrue( dir.exists());
File measuresFile = new File( dir, "VM.properties" );
Assert.assertTrue( measuresFile.exists());
Assert.assertEquals( "", Utils.readFileContent( measuresFile ));
// Verify updates work
final String content = "target: ec2";
map.put( "VM.properties", content.getBytes( "UTF-8" ));
msg = new MsgCmdUpdateProbeConfiguration( "/" + app.getTomcatVm(), map );
processor.processMessage( msg );
Assert.assertTrue( measuresFile.exists());
Assert.assertEquals( content, Utils.readFileContent( measuresFile ));
} finally {
Utils.deleteFilesRecursively( dir );
}
}
@Test
public void testUnknownMessage() {
AgentMessageProcessor processor = new AgentMessageProcessor( new Agent());
processor.processMessage( new Message() {
private static final long serialVersionUID = -3312628850227527510L;
});
}
@Test
public void checkIoExceptionsAreHandled() {
this.client.failMessageSending.set( true );
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
processor.scopedInstance = new TestApplicationTemplate().getMySqlVm();
processor.processMessage( new MsgCmdSendInstances());
// The processor won't be able to send the model through the messaging.
}
@Test
public void testFindPlugin_simulation() {
Instance inst = new Instance( "my inst" );
Agent agent = new Agent();
// No component and no installer
Assert.assertEquals( PluginMock.class, agent.findPlugin( inst ).getClass());
// With an installer
inst.setComponent( new Component( "comp" ).installerName( "inst" ));
Assert.assertEquals( PluginMock.class, agent.findPlugin( inst ).getClass());
}
@Test
public void testFindPlugin_ipojo() {
Instance inst = new Instance( "my inst" );
Agent agent = new Agent();
agent.simulatePlugins = false;
// No component and no installer
Assert.assertNull( agent.findPlugin( inst ));
// With an installer
inst.setComponent( new Component( "comp" ).installerName( "inst" ));
Assert.assertNull( agent.findPlugin( inst ));
// With some plug-ins
PluginMock plugin = new PluginMock();
agent.plugins.add( plugin );
Assert.assertNull( agent.findPlugin( inst ));
inst.getComponent().setInstallerName( plugin.getPluginName());
Assert.assertEquals( plugin, agent.findPlugin( inst ));
}
@Test
public void testExtensibilityNotifications() {
Agent agent = new Agent();
PluginMock pi = new PluginMock();
Assert.assertEquals( 0, agent.plugins.size());
agent.pluginAppears( pi );
Assert.assertEquals( 1, agent.plugins.size());
agent.pluginWasModified( pi );
Assert.assertEquals( 1, agent.plugins.size());
agent.pluginDisappears( pi );
Assert.assertEquals( 0, agent.plugins.size());
agent.pluginDisappears( null );
Assert.assertEquals( 0, agent.plugins.size());
agent.pluginWasModified( pi );
agent.plugins.add( new PluginMock());
agent.plugins.add( new PluginMock());
Assert.assertEquals( 2, agent.plugins.size());
}
@Test
public void testApplicationBinding_noPrevious_noImportAdded() throws IllegalAccessException {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
// Create a binding
Assert.assertEquals( 0, processor.applicationBindings.size());
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
MsgCmdChangeBinding msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo" )));
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo" )), processor.applicationBindings.get( "ext" ));
// No imported added before => nothing to update
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
}
@Test
public void testApplicationBinding_noPrevious_noImportAdded_noNPE() throws IllegalAccessException {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
// Create a binding
Assert.assertEquals( 0, processor.applicationBindings.size());
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
MsgCmdChangeBinding msg = new MsgCmdChangeBinding( "ext", null );
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertTrue( processor.applicationBindings.containsKey( "ext" ));
Assert.assertEquals( null, processor.applicationBindings.get( "ext" ));
// No imported added before => nothing to update
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
}
@Test
public void testApplicationBinding_withPrevious_noImportAdded() throws IllegalAccessException {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
// Create a first binding
MsgCmdChangeBinding msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo1" )));
processor.processMessage( msg );
// Change the binding
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo2" )));
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( 1, processor.applicationBindings.get( "ext" ).size());
Assert.assertTrue( processor.applicationBindings.get( "ext" ).contains( "demo2" ));
Assert.assertEquals( 0, processor.applicationNameToExternalExports.size());
}
@Test
public void testApplicationBinding_withPrevious_importsAdded() throws IllegalAccessException {
// Initialize all the stuff
AgentMessageProcessor processor = (AgentMessageProcessor) this.agent.getMessagingClient().getMessageProcessor();
TestApplicationTemplate app = new TestApplicationTemplate();
processor.scopedInstance = app.getTomcatVm();
ImportedVariable var = new ImportedVariable( "ext.ip", false, true );
app.getTomcatVm().getComponent().importedVariables.put( var.getName(), var );
// Simulate incoming "external" variables
processor.processMessage( new MsgCmdAddImport( "demo1", "ext", "/toto-1", new HashMap<String,String>( 0 )));
processor.processMessage( new MsgCmdAddImport( "demo2", "ext", "/toto", new HashMap<String,String>( 0 )));
processor.processMessage( new MsgCmdAddImport( "demo1", "ext", "/toto-2", new HashMap<String,String>( 0 )));
Assert.assertEquals( 0, processor.applicationBindings.size());
Assert.assertEquals( 2, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 2, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo2" ).size());
Assert.assertEquals( 0, app.getTomcatVm().getImports().size());
// Create a first binding
MsgCmdChangeBinding msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo1" )));
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo1" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 2, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 2, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo2" ).size());
Assert.assertEquals( 1, app.getTomcatVm().getImports().size());
Assert.assertEquals( 2, app.getTomcatVm().getImports().get( "ext" ).size());
// Update the bindings
msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo1", "demo2" )));
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo1", "demo2" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 2, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 2, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo2" ).size());
Assert.assertEquals( 1, app.getTomcatVm().getImports().size());
Assert.assertEquals( 3, app.getTomcatVm().getImports().get( "ext" ).size());
// Simulate a removed import
processor.processMessage( new MsgCmdRemoveImport( "demo1", "ext", "/toto-1" ));
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo1", "demo2" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 2, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo2" ).size());
Assert.assertEquals( 1, app.getTomcatVm().getImports().size());
Assert.assertEquals( 2, app.getTomcatVm().getImports().get( "ext" ).size());
// Try to remove an invalid import
processor.processMessage( new MsgCmdRemoveImport( "demo2", "ext", "/toto-invalid-path" ));
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo1", "demo2" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 2, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo2" ).size());
Assert.assertEquals( 1, app.getTomcatVm().getImports().size());
Assert.assertEquals( 2, app.getTomcatVm().getImports().get( "ext" ).size());
// And simulate another once
processor.processMessage( new MsgCmdRemoveImport( "demo2", "ext", "/toto" ));
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo1", "demo2" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 1, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertNull( processor.applicationNameToExternalExports.get( "demo2" ));
Assert.assertEquals( 1, app.getTomcatVm().getImports().size());
// Update application bindings
// The only remaining import is associated with "demo1"
msg = new MsgCmdChangeBinding( "ext", new HashSet<>( Arrays.asList( "demo2" )));
processor.processMessage( msg );
Assert.assertEquals( 1, processor.applicationBindings.size());
Assert.assertEquals( new HashSet<>( Arrays.asList( "demo2" )), processor.applicationBindings.get( "ext" ));
Assert.assertEquals( 1, processor.applicationNameToExternalExports.size());
Assert.assertEquals( 1, processor.applicationNameToExternalExports.get( "demo1" ).size());
Assert.assertNull( processor.applicationNameToExternalExports.get( "demo2" ));
// No more imports because the last referenced imports matches an application "demo1"
// for which there is no more bound.
Assert.assertEquals( 0, app.getTomcatVm().getImports().size());
}
}