DockerMachineConfigurator implements MachineConfigurator { void createContainer( String imageId ) throws TargetException { this.logger.info( "Creating container " + this.machineId + " from image " + imageId ); Map<String,String> targetProperties = this.parameters.getTargetProperties(); String applicationName = this.parameters.getApplicationName(); String scopedInstancePath = this.parameters.getScopedInstancePath(); Map<String,String> options = new HashMap<> (); for( Map.Entry<String,String> entry : targetProperties.entrySet()) { if( entry.getKey().toLowerCase().startsWith( OPTION_PREFIX_RUN )) { String key = entry.getKey().substring( OPTION_PREFIX_RUN.length()); options.put( key, entry.getValue()); } } List<String> env = new ArrayList<> (); for( Map.Entry<String,String> entry : targetProperties.entrySet()) { if( entry.getKey().toLowerCase().startsWith( OPTION_PREFIX_ENV )) { String key = entry.getKey().substring( OPTION_PREFIX_ENV.length()); String value = entry.getValue(); value = value.replace( "<application-name>", applicationName ); value = value.replace( "<scoped-instance-path>", scopedInstancePath ); value = value.replace( "<scoped-messaging_type>", Utils.getValue( this.parameters.getMessagingProperties(), MessagingConstants.MESSAGING_TYPE_PROPERTY, "" )); env.add( key + "=" + value ); } } String rbcfVersion = DockerUtils.findDefaultImageVersion( ManifestUtils.findBundleVersion()); env.add( "RBCF_VERSION=" + rbcfVersion ); env.add( "AGENT_PARAMETERS=file:" + USER_DATA_DIR + USER_DATA_FILE ); try { String containerName = DockerUtils.buildContainerNameFrom( scopedInstancePath, applicationName ); File dir = new File( this.userDataVolume, containerName ); Utils.createDirectory( dir ); this.containerIdToVolume.put( containerName, dir ); String userData = UserDataHelpers.writeUserDataAsString( this.parameters.getMessagingProperties(), this.parameters.getDomain(), this.parameters.getApplicationName(), this.parameters.getScopedInstancePath()); Utils.writeStringInto( userData, new File( dir, USER_DATA_FILE )); Volume volume = new Volume( USER_DATA_DIR ); Bind volumeBind = new Bind( dir.getAbsolutePath(), volume ); CreateContainerCmd cmd = this.dockerClient.createContainerCmd( imageId ) .withName( containerName ) .withEnv( env ) .withVolumes( Arrays.asList( volume )) .withBinds( Arrays.asList( volumeBind )); DockerUtils.configureOptions( options, cmd ); CreateContainerResponse container = cmd.exec(); if( container.getWarnings() != null && container.getWarnings().length > 0 && this.logger.isLoggable( Level.FINE )) { StringBuilder sb = new StringBuilder(); sb.append( "The following warnings have been found.\n" ); for( String s : container.getWarnings()) sb.append( s ).append( '\n' ); this.logger.fine( sb.toString().trim()); } this.dockerClient.startContainerCmd( container.getId()).exec(); this.logger.fine( "Container " + this.machineId + " was succesfully created as " + container.getId()); this.parameters.getScopedInstance().data.put( Instance.MACHINE_ID, container.getId()); } catch( Exception e ) { throw new TargetException( e ); } } DockerMachineConfigurator(
			TargetHandlerParameters parameters,
			String machineId,
			File userDataVolume,
			Map<String,File> containerIdToVolume ); TargetHandlerParameters getParameters(); @Override Instance getScopedInstance(); @Override void close(); @Override boolean configure();  }
@Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void testCreateContainer_success() throws Exception { CreateContainerCmd ccc = Mockito.mock( CreateContainerCmd.class ); Mockito.when( ccc.withEnv( Mockito.anyListOf( String.class ))).thenReturn( ccc ); Mockito.when( ccc.withBinds( Mockito.anyListOf( Bind.class ))).thenReturn( ccc ); Mockito.when( ccc.withVolumes( Mockito.anyListOf( Volume.class ))).thenReturn( ccc ); Mockito.when( ccc.withName( Mockito.anyString())).thenReturn( ccc ); Mockito.when( this.dockerClient.createContainerCmd( Mockito.anyString())).thenReturn( ccc ); CreateContainerResponse containerResponse = Mockito.mock( CreateContainerResponse.class ); Mockito.when( ccc.exec()).thenReturn( containerResponse ); Mockito.when( containerResponse.getId()).thenReturn( "cid" ); StartContainerCmd scc = Mockito.mock( StartContainerCmd.class ); Mockito.when( this.dockerClient.startContainerCmd( Mockito.anyString())).thenReturn( scc ); final String imageId = "toto"; this.configurator.createContainer( imageId ); Mockito.verify( this.dockerClient ).createContainerCmd( imageId ); Mockito.verify( this.dockerClient ).startContainerCmd( "cid" ); Mockito.verifyNoMoreInteractions( this.dockerClient ); Assert.assertEquals( 1, this.containerIdToVolume.size()); File dir = this.containerIdToVolume.values().iterator().next(); Assert.assertTrue( dir.isDirectory()); Assert.assertTrue( new File( dir, USER_DATA_FILE ).isFile()); Mockito.verify( ccc ).withName( Mockito.anyString()); ArgumentCaptor<List> env = ArgumentCaptor.forClass( List.class ); Mockito.verify( ccc ).withEnv( env.capture()); List<String> effectiveEnv = env.getValue(); Assert.assertEquals( 2, effectiveEnv.size()); Assert.assertEquals( "RBCF_VERSION=latest", effectiveEnv.get( 0 )); Assert.assertEquals( "AGENT_PARAMETERS=file:" + USER_DATA_DIR + USER_DATA_FILE, effectiveEnv.get( 1 )); ArgumentCaptor<List> volumes = ArgumentCaptor.forClass( List.class ); Mockito.verify( ccc ).withVolumes( volumes.capture()); List<Volume> effectiveVolumes = volumes.getValue(); Assert.assertNotNull( effectiveVolumes ); Assert.assertEquals( 1, effectiveVolumes.size()); Volume effectiveVolume = effectiveVolumes.get( 0 ); Assert.assertNotNull( effectiveVolume ); Assert.assertEquals( USER_DATA_DIR, effectiveVolume.getPath()); ArgumentCaptor<List> bounds = ArgumentCaptor.forClass( List.class ); Mockito.verify( ccc ).withBinds( bounds.capture()); List<Bind> effectiveBounds = bounds.getValue(); Assert.assertNotNull( effectiveBounds ); Assert.assertEquals( 1, effectiveBounds.size()); Bind effectiveBind = effectiveBounds.get( 0 ); Assert.assertNotNull( effectiveBind ); Assert.assertEquals( dir.getAbsolutePath(), effectiveBind.getPath()); Assert.assertEquals( effectiveVolume, effectiveBind.getVolume()); }
@Test public void testCreateContainer_loggedWarnings() throws Exception { CreateContainerCmd ccc = Mockito.mock( CreateContainerCmd.class ); Mockito.when( ccc.withEnv( Mockito.anyListOf( String.class ))).thenReturn( ccc ); Mockito.when( ccc.withBinds( Mockito.anyListOf( Bind.class ))).thenReturn( ccc ); Mockito.when( ccc.withVolumes( Mockito.anyListOf( Volume.class ))).thenReturn( ccc ); Mockito.when( ccc.withName( Mockito.anyString())).thenReturn( ccc ); CreateContainerResponse containerResponse = Mockito.mock( CreateContainerResponse.class ); Mockito.when( this.dockerClient.createContainerCmd( Mockito.anyString())).thenReturn( ccc ); Mockito.when( ccc.exec()).thenReturn( containerResponse ); Mockito.when( containerResponse.getId()).thenReturn( "cid" ); StartContainerCmd scc = Mockito.mock( StartContainerCmd.class ); Mockito.when( this.dockerClient.startContainerCmd( Mockito.anyString())).thenReturn( scc ); this.configurator.logger = Mockito.mock( Logger.class ); Mockito.when( this.configurator.logger.isLoggable( Level.FINE )).thenReturn( true ); Mockito.when( containerResponse.getWarnings()).thenReturn( new String[]{ "Not good.", "Stay well." }); final String imageId = "toto"; this.configurator.createContainer( imageId ); Mockito.verify( this.dockerClient ).createContainerCmd( imageId ); Mockito.verify( this.dockerClient ).startContainerCmd( "cid" ); Mockito.verifyNoMoreInteractions( this.dockerClient ); Mockito.verify( containerResponse, Mockito.times( 3 )).getWarnings(); Mockito.verify( this.configurator.logger ).fine( "The following warnings have been found.\nNot good.\nStay well." ); }
@Test( expected = TargetException.class ) public void testCreateContainer_exception() throws Exception { CreateContainerCmd ccc = Mockito.mock( CreateContainerCmd.class ); Mockito.when( ccc.withEnv( Mockito.anyListOf( String.class ))).thenReturn( ccc ); Mockito.when( ccc.withName( Mockito.anyString())).thenReturn( ccc ); Mockito.when( this.dockerClient.createContainerCmd( Mockito.anyString())).thenThrow( new RuntimeException( "for test" )); final String imageId = "toto"; this.configurator.createContainer( imageId ); }