/**
* Copyright 2015-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.dm.internal.api.impl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Logger;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import net.roboconf.core.Constants;
import net.roboconf.core.ErrorCode;
import net.roboconf.core.RoboconfError;
import net.roboconf.core.internal.tests.TestApplication;
import net.roboconf.core.internal.tests.TestApplicationTemplate;
import net.roboconf.core.model.ApplicationDescriptor;
import net.roboconf.core.model.beans.Application;
import net.roboconf.core.model.beans.ApplicationTemplate;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.api.IRandomMngr;
import net.roboconf.dm.internal.test.TestManagerWrapper;
import net.roboconf.dm.internal.utils.ConfigurationUtils;
import net.roboconf.dm.management.ManagedApplication;
import net.roboconf.dm.management.api.IApplicationTemplateMngr;
import net.roboconf.dm.management.api.IAutonomicMngr;
import net.roboconf.dm.management.api.IConfigurationMngr;
import net.roboconf.dm.management.api.IMessagingMngr;
import net.roboconf.dm.management.api.INotificationMngr;
import net.roboconf.dm.management.api.ITargetsMngr;
import net.roboconf.dm.management.exceptions.AlreadyExistingException;
import net.roboconf.dm.management.exceptions.InvalidApplicationException;
import net.roboconf.dm.management.exceptions.UnauthorizedActionException;
import net.roboconf.messaging.api.business.IDmClient;
import net.roboconf.messaging.api.business.ListenerCommand;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdChangeBinding;
/**
* @author Vincent Zurczak - Linagora
*/
public class ApplicationMngrImplTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private ApplicationMngrImpl mngr;
private IMessagingMngr messagingMngr;
private IConfigurationMngr configurationMngr;
private IApplicationTemplateMngr applicationTemplateMngr;
private IAutonomicMngr autonomicMngr;
private File dmDirectory;
private IDmClient dmClientMock;
@Before
public void prepareTemplateManager() throws Exception {
INotificationMngr notificationMngr = Mockito.mock( INotificationMngr.class );
ITargetsMngr targetsMngr = Mockito.mock( ITargetsMngr.class );
IRandomMngr randomMngr = Mockito.mock( IRandomMngr.class );
this.messagingMngr = Mockito.mock( IMessagingMngr.class );
this.dmClientMock = Mockito.mock( IDmClient.class );
Mockito.when( this.messagingMngr.getMessagingClient()).thenReturn( this.dmClientMock );
this.autonomicMngr = Mockito.mock( IAutonomicMngr.class );
this.configurationMngr = Mockito.mock( IConfigurationMngr.class );
this.applicationTemplateMngr = Mockito.mock( IApplicationTemplateMngr.class );
this.mngr = new ApplicationMngrImpl(
notificationMngr, this.configurationMngr,
targetsMngr, this.messagingMngr,
randomMngr, this.autonomicMngr );
this.mngr.setApplicationTemplateMngr( this.applicationTemplateMngr );
this.dmDirectory = this.folder.newFolder();
Mockito.when( this.configurationMngr.getWorkingDirectory()).thenReturn( this.dmDirectory );
}
@Test
public void testIsTemplateUsed() throws Exception {
ApplicationTemplate tpl = new ApplicationTemplate( "lamp" );
Assert.assertFalse( this.mngr.isTemplateUsed( tpl ));
ManagedApplication ma = new ManagedApplication( new Application( "app", tpl ));
ma.getApplication().setDirectory( this.folder.newFolder());
TestManagerWrapper.addManagedApplication( this.mngr, ma );
Assert.assertTrue( this.mngr.isTemplateUsed( tpl ));
ApplicationTemplate tpl2 = new ApplicationTemplate( "lamp" ).qualifier( "v2" );
Assert.assertFalse( this.mngr.isTemplateUsed( tpl2 ));
}
@Test( expected = IOException.class )
public void testCreateApplication_invalidApplicationName_1() throws Exception {
this.mngr.createApplication( null, "desc", new ApplicationTemplate());
}
@Test( expected = IOException.class )
public void testCreateApplication_invalidApplicationName_2() throws Exception {
this.mngr.createApplication( "", "desc", new ApplicationTemplate());
}
@Test( expected = IOException.class )
public void testCreateApplication_invalidApplicationName_3() throws Exception {
this.mngr.createApplication( "app#", "desc", new ApplicationTemplate());
}
@Test( expected = UnauthorizedActionException.class )
public void testDeleteApplication_unauthorized() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma );
app.getMySqlVm().setStatus( InstanceStatus.DEPLOYED_STARTED );
this.mngr.deleteApplication( ma );
}
@Test
public void testDeleteApplication_success() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma );
Assert.assertEquals( 1, this.mngr.getManagedApplications().size());
this.mngr.deleteApplication( ma );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).unloadApplicationRules( ma.getApplication());
}
@Test
public void testCreateApplication_success() throws Exception {
TestApplicationTemplate tpl = new TestApplicationTemplate();
tpl.setDirectory( this.folder.newFolder());
Mockito.verifyZeroInteractions( this.applicationTemplateMngr );
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
ManagedApplication ma = this.mngr.createApplication( "toto", "desc", tpl.getName(), tpl.getQualifier());
Assert.assertNotNull( ma );
Assert.assertEquals( 1, TestManagerWrapper.getNameToManagedApplication( this.mngr ).size());
Assert.assertEquals( ma.getDirectory().getName(), ma.getName());
Assert.assertEquals( "toto", ma.getName());
File expected = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.APPLICATIONS );
Assert.assertEquals( expected, ma.getDirectory().getParentFile());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).loadApplicationRules( ma.getApplication());
}
@Test
public void testCreateApplication_success_withSpecialName() throws Exception {
TestApplicationTemplate tpl = new TestApplicationTemplate();
tpl.setDirectory( this.folder.newFolder());
Mockito.verifyZeroInteractions( this.applicationTemplateMngr );
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
ManagedApplication ma = this.mngr.createApplication( "ça débute", "desc", tpl.getName(), tpl.getQualifier());
Assert.assertNotNull( ma );
Assert.assertEquals( "ca debute", ma.getName());
Assert.assertEquals( "ça débute", ma.getApplication().getDisplayName());
Assert.assertEquals( 1, TestManagerWrapper.getNameToManagedApplication( this.mngr ).size());
Assert.assertEquals( ma.getDirectory().getName(), ma.getName());
// Important
Assert.assertNull( this.mngr.findManagedApplicationByName( "ça débute" ));
Assert.assertNull( this.mngr.findApplicationByName( "ça débute" ));
Assert.assertNotNull( this.mngr.findManagedApplicationByName( "ca debute" ));
Assert.assertNotNull( this.mngr.findApplicationByName( "ca debute" ));
// Important
File expected = new File( this.configurationMngr.getWorkingDirectory(), ConfigurationUtils.APPLICATIONS );
Assert.assertEquals( expected, ma.getDirectory().getParentFile());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).loadApplicationRules( ma.getApplication());
}
@Test( expected = AlreadyExistingException.class )
public void testCreateApplication_conflict() throws Exception {
TestApplicationTemplate tpl = new TestApplicationTemplate();
tpl.setDirectory( this.folder.newFolder());
Mockito.verifyZeroInteractions( this.applicationTemplateMngr );
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
ManagedApplication ma = this.mngr.createApplication( "toto", "desc", tpl.getName(), tpl.getQualifier());
Assert.assertNotNull( ma );
Assert.assertEquals( 1, TestManagerWrapper.getNameToManagedApplication( this.mngr ).size());
this.mngr.createApplication( "toto", "desc", tpl );
}
@Test
public void testUpdateApplication_success() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma );
String newDesc = "new description";
Assert.assertEquals( 0, app.getDirectory().listFiles().length );
Assert.assertFalse( newDesc.equals( app.getDescription()));
this.mngr.updateApplication( ma, newDesc );
Assert.assertEquals( newDesc, app.getDescription());
Assert.assertEquals( 1, app.getDirectory().listFiles().length );
}
@Test( expected = IOException.class )
public void testUpdateApplication_saveFailure() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFile());
ManagedApplication ma = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma );
String newDesc = "new description";
this.mngr.updateApplication( ma, newDesc );
}
@Test( expected = InvalidApplicationException.class )
public void testCreateApplication_invalidTemplate() throws Exception {
this.mngr.createApplication( "toto", "desc", "whatever", null );
}
@Test
public void testRestoreApplications_noTemplate_noDirectory() throws Exception {
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
}
@Test
public void testRestoreApplications_noTemplate_withTplDirectory() throws Exception {
Assert.assertTrue( new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS ).mkdir());
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
}
@Test
public void testRestoreApplications_withApp() throws Exception {
File dir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/myApp/" + Constants.PROJECT_DIR_DESC );
File descriptorFile = new File( dir, Constants.PROJECT_FILE_DESCRIPTOR );
Assert.assertTrue( dir.mkdirs());
ApplicationTemplate tpl = new ApplicationTemplate( "myTpl" ).qualifier( "v1" );
tpl.setDirectory( this.folder.newFolder());
Application app = new Application( "myApp", tpl );
ApplicationDescriptor.save( descriptorFile, app );
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Mockito.verifyZeroInteractions( this.dmClientMock );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 1, this.mngr.getManagedApplications().size());
Mockito.verify( this.dmClientMock, Mockito.times( 1 )).listenToAgentMessages( app, ListenerCommand.START );
ManagedApplication ma = this.mngr.getManagedApplications().iterator().next();
Assert.assertEquals( app.getName(), ma.getName());
Assert.assertEquals( tpl.getName(), app.getTemplate().getName());
Assert.assertEquals( tpl.getQualifier(), app.getTemplate().getQualifier());
Assert.assertEquals( dir.getParentFile(), ma.getDirectory());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).loadApplicationRules( ma.getApplication());
}
@Test
public void testRestoreApplications_withApp_withSpecialName() throws Exception {
File dir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/ca debute bien/" + Constants.PROJECT_DIR_DESC );
File descriptorFile = new File( dir, Constants.PROJECT_FILE_DESCRIPTOR );
Assert.assertTrue( dir.mkdirs());
ApplicationTemplate tpl = new ApplicationTemplate( "myTpl" ).qualifier( "v1" );
tpl.setDirectory( this.folder.newFolder());
Application app = new Application( "ça débute bien", tpl );
ApplicationDescriptor.save( descriptorFile, app );
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Mockito.verifyZeroInteractions( this.dmClientMock );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 1, this.mngr.getManagedApplications().size());
Mockito.verify( this.dmClientMock, Mockito.times( 1 )).listenToAgentMessages( app, ListenerCommand.START );
ManagedApplication ma = this.mngr.getManagedApplications().iterator().next();
Assert.assertEquals( "ca debute bien", ma.getName());
Assert.assertEquals( "ça débute bien", ma.getApplication().getDisplayName());
Assert.assertEquals( tpl.getName(), app.getTemplate().getName());
Assert.assertEquals( tpl.getQualifier(), app.getTemplate().getQualifier());
Assert.assertEquals( dir.getParentFile(), ma.getDirectory());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).loadApplicationRules( ma.getApplication());
}
@Test
public void testRestoreApplications_withConflict() throws Exception {
ApplicationTemplate tpl = new ApplicationTemplate( "myTpl" ).qualifier( "v1" );
tpl.setDirectory( this.folder.newFolder());
Application app = new Application( "myApp", tpl );
// Copy the application descriptor twice
for( int i=0; i<2; i++ ) {
File dir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/myApp" + i + "/" + Constants.PROJECT_DIR_DESC );
File descriptorFile = new File( dir, Constants.PROJECT_FILE_DESCRIPTOR );
Assert.assertTrue( dir.mkdirs());
ApplicationDescriptor.save( descriptorFile, app );
}
Mockito.when( this.applicationTemplateMngr.findTemplate( tpl.getName(), tpl.getQualifier())).thenReturn( tpl );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 1, this.mngr.getManagedApplications().size());
ManagedApplication ma = this.mngr.getManagedApplications().iterator().next();
Assert.assertEquals( app.getName(), ma.getName());
Assert.assertEquals( tpl.getName(), app.getTemplate().getName());
Assert.assertEquals( tpl.getQualifier(), app.getTemplate().getQualifier());
Mockito.verify( this.autonomicMngr, Mockito.times( 1 )).loadApplicationRules( ma.getApplication());
}
@Test
public void testRestoreApplications_withError() throws Exception {
File tplDir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/Demo" );
Assert.assertTrue( tplDir.mkdirs());
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
}
@Test
public void testRestoreApplications_invalidApplicationTemplate() throws Exception {
File dir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/myApp/" + Constants.PROJECT_DIR_DESC );
File descriptorFile = new File( dir, Constants.PROJECT_FILE_DESCRIPTOR );
Assert.assertTrue( dir.mkdirs());
Application app = new Application( "myApp", new ApplicationTemplate( "not" ).qualifier( "valid" ));
ApplicationDescriptor.save( descriptorFile, app );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
}
@Test
public void testRestoreApplications_invalidApplicationDescriptor() throws Exception {
File dir = new File( this.dmDirectory, ConfigurationUtils.APPLICATIONS + "/myApp/" + Constants.PROJECT_DIR_DESC );
File descriptorFile = new File( dir, Constants.PROJECT_FILE_DESCRIPTOR );
Assert.assertTrue( dir.mkdirs());
Utils.writeStringInto( "invalid", descriptorFile );
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
this.mngr.restoreApplications();
Assert.assertEquals( 0, this.mngr.getManagedApplications().size());
}
@Test
public void testCheckErrors_noError() throws Exception {
ApplicationMngrImpl.checkErrors( new ArrayList<RoboconfError>( 0 ), Logger.getLogger( getClass().getName()));
// No exception
}
@Test( expected = InvalidApplicationException.class )
public void testCheckErrors_withError() throws Exception {
List<RoboconfError> errors = new ArrayList<> ();
errors.add( new RoboconfError( ErrorCode.CO_CYCLE_IN_COMPONENTS_INHERITANCE ));
ApplicationMngrImpl.checkErrors( errors, Logger.getLogger( getClass().getName()));
}
@Test
public void testCheckErrors_withWarning() throws Exception {
List<RoboconfError> errors = new ArrayList<> ();
errors.add( new RoboconfError( ErrorCode.RM_MISSING_APPLICATION_DSL_ID ));
ApplicationMngrImpl.checkErrors( errors, Logger.getLogger( getClass().getName()));
// No exception
}
@Test( expected = UnauthorizedActionException.class )
public void testBindApplication_invalidApplication() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma );
this.mngr.bindOrUnbindApplication( ma, ma.getApplication().getTemplate().getName(), "invalid", true );
}
@Test( expected = UnauthorizedActionException.class )
public void testBindApplication_invalidTemplate() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma1 = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
app = new TestApplication();
app.getTemplate().setName( "tpl-other" );
app.setName( "app-other" );
app.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
// ma1 and ma2 do not have the same template name
this.mngr.bindOrUnbindApplication( ma1, ma1.getApplication().getTemplate().getName(), ma2.getName(), true );
}
@Test( expected = UnauthorizedActionException.class )
public void testBindApplication_invalidTemplatePrefix() throws Exception {
TestApplication app = new TestApplication();
app.setDirectory( this.folder.newFolder());
app.getTemplate().setExternalExportsPrefix( "prefix" );
ManagedApplication ma1 = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
app = new TestApplication();
app.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
// ma1 and ma2 do not have the same template name
this.mngr.bindOrUnbindApplication( ma1, ma1.getApplication().getTemplate().getName(), ma2.getName(), true );
}
@Test
public void testBindApplication_success() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
TestApplication app2 = new TestApplication();
app2.getTemplate().setName( "tpl-other" );
app2.getTemplate().setExternalExportsPrefix( "tpl-other-prefix" );
app2.getTemplate().setExternalExportsPrefix( "prefix2" );
app2.setName( "app-other" );
// Rename root instances in the second application.
// This is to make sure messages are sent to the right instances in the right application.
app2.getMySqlVm().setName( "other-mysql" );
app2.getTomcatVm().setName( "other-tomcat" );
app2.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app2 );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
String eep = ma2.getApplication().getTemplate().getExternalExportsPrefix();
Mockito.verifyZeroInteractions( this.messagingMngr );
this.mngr.bindOrUnbindApplication( ma1, eep, ma2.getName(), true );
Assert.assertEquals( 1, ma1.getApplication().getApplicationBindings().size());
Assert.assertTrue( ma1.getApplication().getApplicationBindings().get( eep ).contains( ma2.getName()));
// Verify the messaging
ArgumentCaptor<ManagedApplication> arg0 = ArgumentCaptor.forClass( ManagedApplication.class );
ArgumentCaptor<Instance> arg1 = ArgumentCaptor.forClass( Instance.class );
ArgumentCaptor<Message> arg2 = ArgumentCaptor.forClass( Message.class );
Mockito.verify( this.messagingMngr, Mockito.times( 2 )).sendMessageSafely( arg0.capture(), arg1.capture(), arg2.capture());
for( ManagedApplication s : arg0.getAllValues()) {
Assert.assertEquals( ma1, s );
}
for( Message m : arg2.getAllValues()) {
Assert.assertEquals( MsgCmdChangeBinding.class, m.getClass());
MsgCmdChangeBinding msg = (MsgCmdChangeBinding) m;
Assert.assertEquals( ma2.getApplication().getTemplate().getExternalExportsPrefix(), msg.getExternalExportsPrefix());
Assert.assertNotNull( msg.getAppNames());
Assert.assertEquals( 1, msg.getAppNames().size());
Assert.assertTrue( msg.getAppNames().contains( ma2.getName()));
}
// Messages must be sent to ma1!
List<Instance> instances = arg1.getAllValues();
Assert.assertTrue( instances.contains( app1.getMySqlVm()));
Assert.assertTrue( instances.contains( app1.getTomcatVm()));
}
@Test
public void testUnbindApplication_success_withNotification() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
TestApplication app2 = new TestApplication();
app2.getTemplate().setName( "tpl-other" );
app2.getTemplate().setExternalExportsPrefix( "tpl-other-prefix" );
app2.getTemplate().setExternalExportsPrefix( "prefix2" );
app2.setName( "app-other" );
// Rename root instances in the second application.
// This is to make sure messages are sent to the right instances in the right application.
app2.getMySqlVm().setName( "other-mysql" );
app2.getTomcatVm().setName( "other-tomcat" );
app2.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app2 );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
String eep = ma2.getApplication().getTemplate().getExternalExportsPrefix();
Mockito.verifyZeroInteractions( this.messagingMngr );
this.mngr.bindOrUnbindApplication( ma1, eep, ma2.getName(), true );
Assert.assertEquals( 1, ma1.getApplication().getApplicationBindings().size());
Assert.assertTrue( ma1.getApplication().getApplicationBindings().get( eep ).contains( ma2.getName()));
Mockito.reset( this.messagingMngr );
// Unbind
this.mngr.bindOrUnbindApplication( ma1, eep, ma2.getName(), false );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
// Verify sent messages
ArgumentCaptor<ManagedApplication> arg0 = ArgumentCaptor.forClass( ManagedApplication.class );
ArgumentCaptor<Instance> arg1 = ArgumentCaptor.forClass( Instance.class );
ArgumentCaptor<Message> arg2 = ArgumentCaptor.forClass( Message.class );
Mockito.verify( this.messagingMngr, Mockito.times( 2 )).sendMessageSafely( arg0.capture(), arg1.capture(), arg2.capture());
for( ManagedApplication s : arg0.getAllValues()) {
Assert.assertEquals( ma1, s );
}
for( Message m : arg2.getAllValues()) {
Assert.assertEquals( MsgCmdChangeBinding.class, m.getClass());
MsgCmdChangeBinding msg = (MsgCmdChangeBinding) m;
Assert.assertEquals( ma2.getApplication().getTemplate().getExternalExportsPrefix(), msg.getExternalExportsPrefix());
Assert.assertNull( msg.getAppNames());
}
// Messages must be sent to ma1!
List<Instance> instances = arg1.getAllValues();
Assert.assertTrue( instances.contains( app1.getMySqlVm()));
Assert.assertTrue( instances.contains( app1.getTomcatVm()));
}
@Test
public void testUnbindApplication_success_withoutNotification() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
TestApplication app2 = new TestApplication();
app2.getTemplate().setName( "tpl-other" );
app2.getTemplate().setExternalExportsPrefix( "tpl-other-prefix" );
app2.getTemplate().setExternalExportsPrefix( "prefix2" );
app2.setName( "app-other" );
// Rename root instances in the second application.
// This is to make sure messages are sent to the right instances in the right application.
app2.getMySqlVm().setName( "other-mysql" );
app2.getTomcatVm().setName( "other-tomcat" );
app2.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app2 );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
String eep = ma2.getApplication().getTemplate().getExternalExportsPrefix();
// Unbind an application that is not bound
this.mngr.bindOrUnbindApplication( ma1, eep, ma2.getName(), false );
// Nothing changed
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
// No message should have been sent when we tried to unbind
Mockito.verifyZeroInteractions( this.messagingMngr );
}
@Test
public void testReplaceApplicationBindings_success() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
TestApplication app2 = new TestApplication();
app2.setDirectory( this.folder.newFolder());
app2.getTemplate().setName( "tpl-other" );
app2.getTemplate().setExternalExportsPrefix( "tpl-other-prefix" );
app2.getTemplate().setExternalExportsPrefix( "prefix2" );
app2.setName( "app-other" );
// Rename root instances in the second application.
// This is to make sure messages are sent to the right instances in the right application.
app2.getMySqlVm().setName( "other-mysql" );
app2.getTomcatVm().setName( "other-tomcat" );
ManagedApplication ma2 = new ManagedApplication( app2 );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
String eep = ma2.getApplication().getTemplate().getExternalExportsPrefix();
Mockito.verifyZeroInteractions( this.messagingMngr );
this.mngr.replaceApplicationBindings( ma1, eep, new HashSet<>( Arrays.asList( ma2.getName())));
Assert.assertEquals( 1, ma1.getApplication().getApplicationBindings().size());
Assert.assertTrue( ma1.getApplication().getApplicationBindings().get( eep ).contains( ma2.getName()));
// Verify the messaging
ArgumentCaptor<ManagedApplication> arg0 = ArgumentCaptor.forClass( ManagedApplication.class );
ArgumentCaptor<Instance> arg1 = ArgumentCaptor.forClass( Instance.class );
ArgumentCaptor<Message> arg2 = ArgumentCaptor.forClass( Message.class );
Mockito.verify( this.messagingMngr, Mockito.times( 2 )).sendMessageSafely( arg0.capture(), arg1.capture(), arg2.capture());
for( ManagedApplication s : arg0.getAllValues()) {
Assert.assertEquals( ma1, s );
}
for( Message m : arg2.getAllValues()) {
Assert.assertEquals( MsgCmdChangeBinding.class, m.getClass());
MsgCmdChangeBinding msg = (MsgCmdChangeBinding) m;
Assert.assertEquals( ma2.getApplication().getTemplate().getExternalExportsPrefix(), msg.getExternalExportsPrefix());
Assert.assertNotNull( msg.getAppNames());
Assert.assertEquals( 1, msg.getAppNames().size());
Assert.assertTrue( msg.getAppNames().contains( ma2.getName()));
}
// Messages must be sent to ma1!
List<Instance> instances = arg1.getAllValues();
Assert.assertTrue( instances.contains( app1.getMySqlVm()));
Assert.assertTrue( instances.contains( app1.getTomcatVm()));
// Set the same bindings: no message should be sent
Mockito.reset( this.messagingMngr );
this.mngr.replaceApplicationBindings( ma1, eep, new HashSet<>( Arrays.asList( ma2.getName())));
Mockito.verifyZeroInteractions( this.messagingMngr );
// Change the binding to an empty list => there should be messages
this.mngr.replaceApplicationBindings( ma1, eep, new HashSet<String>( 0 ));
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
// Verify the messaging
arg0 = ArgumentCaptor.forClass( ManagedApplication.class );
arg1 = ArgumentCaptor.forClass( Instance.class );
arg2 = ArgumentCaptor.forClass( Message.class );
Mockito.verify( this.messagingMngr, Mockito.times( 2 )).sendMessageSafely( arg0.capture(), arg1.capture(), arg2.capture());
for( ManagedApplication s : arg0.getAllValues()) {
Assert.assertEquals( ma1, s );
}
for( Message m : arg2.getAllValues()) {
Assert.assertEquals( MsgCmdChangeBinding.class, m.getClass());
MsgCmdChangeBinding msg = (MsgCmdChangeBinding) m;
Assert.assertEquals( ma2.getApplication().getTemplate().getExternalExportsPrefix(), msg.getExternalExportsPrefix());
Assert.assertNull( msg.getAppNames());
}
}
@Test( expected = UnauthorizedActionException.class )
public void testReplaceApplicationBindings_failure_inexistingApplication() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
Mockito.verifyZeroInteractions( this.messagingMngr );
this.mngr.replaceApplicationBindings( ma1, "prefix1", new HashSet<>( Arrays.asList( "inexisting" )));
}
@Test( expected = UnauthorizedActionException.class )
public void testReplaceApplicationBindings_failure_invalidTemplate() throws Exception {
TestApplication app1 = new TestApplication();
app1.setDirectory( this.folder.newFolder());
app1.getTemplate().setExternalExportsPrefix( "prefix1" );
ManagedApplication ma1 = new ManagedApplication( app1 );
TestManagerWrapper.addManagedApplication( this.mngr, ma1 );
TestApplication app2 = new TestApplication();
app2.setDirectory( this.folder.newFolder());
ManagedApplication ma2 = new ManagedApplication( app2 );
TestManagerWrapper.addManagedApplication( this.mngr, ma2 );
Assert.assertEquals( 0, ma1.getApplication().getApplicationBindings().size());
Mockito.verifyZeroInteractions( this.messagingMngr );
this.mngr.replaceApplicationBindings( ma1, "prefix1", new HashSet<>( Arrays.asList( ma2.getName())));
}
}