/**
* 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.dm.rest.client.delegates;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Timer;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.grizzly.http.server.HttpServer;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import net.roboconf.core.Constants;
import net.roboconf.core.internal.tests.TestApplication;
import net.roboconf.core.internal.tests.TestUtils;
import net.roboconf.core.model.beans.Component;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.ComponentHelpers;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.Utils;
import net.roboconf.dm.internal.test.TestManagerWrapper;
import net.roboconf.dm.internal.test.TestTargetResolver;
import net.roboconf.dm.management.ManagedApplication;
import net.roboconf.dm.management.Manager;
import net.roboconf.dm.rest.client.WsClient;
import net.roboconf.dm.rest.client.exceptions.ApplicationWsException;
import net.roboconf.dm.rest.services.internal.RestApplication;
import net.roboconf.messaging.api.MessagingConstants;
import net.roboconf.messaging.api.internal.client.test.TestClient;
import net.roboconf.messaging.api.messages.Message;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdChangeBinding;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdChangeInstanceState;
import net.roboconf.messaging.api.messages.from_dm_to_agent.MsgCmdResynchronize;
/**
* @author Vincent Zurczak - Linagora
*/
public class ApplicationWsDelegateTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private static final String REST_URI = "http://localhost:8090";
private TestApplication app;
private ManagedApplication ma;
private Manager manager;
private TestManagerWrapper managerWrapper;
private WsClient client;
private HttpServer httpServer;
private TestClient msgClient;
@After
public void after() {
this.manager.stop();
if( this.httpServer != null )
this.httpServer.stop();
if( this.client != null )
this.client.destroy();
}
@Before
public void before() throws Exception {
// Create the manager
this.manager = new Manager();
this.manager.setMessagingType( MessagingConstants.FACTORY_TEST );
this.manager.setTargetResolver( new TestTargetResolver());
this.manager.configurationMngr().setWorkingDirectory( this.folder.newFolder());
this.manager.start();
// Create the wrapper and complete configuration
this.managerWrapper = new TestManagerWrapper( this.manager );
this.managerWrapper.configureMessagingForTest();
this.manager.reconfigure();
// Get the messaging client
this.msgClient = (TestClient) this.managerWrapper.getInternalMessagingClient();
this.msgClient.clearMessages();
// Disable the messages timer for predictability
TestUtils.getInternalField( this.manager, "timer", Timer.class).cancel();
URI uri = UriBuilder.fromUri( REST_URI ).build();
RestApplication restApp = new RestApplication( this.manager );
this.httpServer = GrizzlyServerFactory.createHttpServer( uri, restApp );;
// Load an application
this.app = new TestApplication();
this.app.setDirectory( this.folder.newFolder());
this.ma = new ManagedApplication( this.app );
this.managerWrapper.addManagedApplication( this.ma );
this.client = new WsClient( REST_URI );
}
@Test( expected = ApplicationWsException.class )
public void testChangeState_inexistingApplication() throws Exception {
this.client.getApplicationDelegate().changeInstanceState( "inexisting", InstanceStatus.DEPLOYED_STARTED, null );
}
@Test( expected = ApplicationWsException.class )
public void testChangeState_inexistingInstance_null() throws Exception {
this.client.getApplicationDelegate().changeInstanceState( this.app.getName(), InstanceStatus.DEPLOYED_STARTED, null );
}
@Test( expected = ApplicationWsException.class )
public void testChangeState_inexistingInstance() throws Exception {
this.client.getApplicationDelegate().changeInstanceState( this.app.getName(), InstanceStatus.DEPLOYED_STARTED, "/bip/bip" );
}
@Test( expected = ApplicationWsException.class )
public void testChangeState_invalidAction() throws Exception {
this.client.getApplicationDelegate().changeInstanceState( this.app.getName(), null, null );
}
@Test
public void testChangeState_deployRoot_success() throws Exception {
TestTargetResolver iaasResolver = new TestTargetResolver();
this.manager.setTargetResolver( iaasResolver );
String targetId = this.manager.targetsMngr().createTarget( "id: tid\nhandler: test" );
this.manager.targetsMngr().associateTargetWith( targetId, this.app, null );
Assert.assertEquals( 0, iaasResolver.instancePathToRunningStatus.size());
this.client.getApplicationDelegate().changeInstanceState(
this.app.getName(),
InstanceStatus.DEPLOYED_STARTED,
InstanceHelpers.computeInstancePath( this.app.getMySqlVm()));
String path = InstanceHelpers.computeInstancePath( this.app.getMySqlVm());
Assert.assertEquals( 1, iaasResolver.instancePathToRunningStatus.size());
Assert.assertTrue( iaasResolver.instancePathToRunningStatus.get( path ));
}
@Test
public void testChangeState_deploy_success() throws Exception {
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getTomcatVm()).size());
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().changeInstanceState( this.app.getName(), InstanceStatus.DEPLOYED_STOPPED, instancePath );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
List<Message> messages = this.ma.removeAwaitingMessages( this.app.getTomcatVm());
Assert.assertEquals( 1, messages.size());
Assert.assertEquals( MsgCmdChangeInstanceState.class, messages.get( 0 ).getClass());
Assert.assertEquals( instancePath, ((MsgCmdChangeInstanceState) messages.get( 0 )).getInstancePath());
}
@Test
public void testSetDescription_ok() throws Exception {
String newDesc = "a new description";
this.app.setDirectory( this.folder.newFolder());
Assert.assertFalse( newDesc.equals( this.app.getDescription()));
this.client.getApplicationDelegate().setDescription( this.app.getName(), newDesc );
Assert.assertEquals( newDesc, this.app.getDescription());
}
@Test( expected = ApplicationWsException.class )
public void testSetDescription_noApp() throws Exception {
this.client.getApplicationDelegate().setDescription( "error", "new description" );
}
@Test
public void testStopAll() throws Exception {
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getTomcatVm()).size());
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().stopAll( this.app.getName(), instancePath );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
List<Message> messages = this.ma.removeAwaitingMessages( this.app.getTomcatVm());
Assert.assertEquals( 1, messages.size());
Assert.assertEquals( MsgCmdChangeInstanceState.class, messages.get( 0 ).getClass());
Assert.assertEquals( instancePath, ((MsgCmdChangeInstanceState) messages.get( 0 )).getInstancePath());
}
@Test( expected = ApplicationWsException.class )
public void testStopAll_invalidApp() throws Exception {
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().stopAll( "oops", instancePath );
}
@Test
public void testUndeployAll() throws Exception {
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getTomcatVm()).size());
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().undeployAll( this.app.getName(), instancePath );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
List<Message> messages = this.ma.removeAwaitingMessages( this.app.getTomcatVm());
Assert.assertEquals( 1, messages.size());
Assert.assertEquals( MsgCmdChangeInstanceState.class, messages.get( 0 ).getClass());
Assert.assertEquals( instancePath, ((MsgCmdChangeInstanceState) messages.get( 0 )).getInstancePath());
}
@Test( expected = ApplicationWsException.class )
public void testUndeployAll_invalidApp() throws Exception {
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().undeployAll( "oops", instancePath );
}
@Test
public void testDeployAndStartAll() throws Exception {
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getTomcatVm()).size());
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().deployAndStartAll( this.app.getName(), instancePath );
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
List<Message> messages = this.ma.removeAwaitingMessages( this.app.getTomcatVm());
Assert.assertEquals( 2, messages.size());
Assert.assertEquals( MsgCmdChangeInstanceState.class, messages.get( 0 ).getClass());
Assert.assertEquals( InstanceHelpers.computeInstancePath( this.app.getTomcat()), ((MsgCmdChangeInstanceState) messages.get( 0 )).getInstancePath());
Assert.assertEquals( MsgCmdChangeInstanceState.class, messages.get( 1 ).getClass());
Assert.assertEquals( InstanceHelpers.computeInstancePath( this.app.getWar()), ((MsgCmdChangeInstanceState) messages.get( 1 )).getInstancePath());
}
@Test( expected = ApplicationWsException.class )
public void testDeployAndStartAll_invalidApp() throws Exception {
String instancePath = InstanceHelpers.computeInstancePath( this.app.getTomcat());
this.client.getApplicationDelegate().deployAndStartAll( "oops", instancePath );
}
@Test
public void testListChildrenInstances() throws Exception {
List<Instance> instances = this.client.getApplicationDelegate().listChildrenInstances( this.app.getName(), "/bip/bip", false );
Assert.assertEquals( 0, instances.size());
instances = this.client.getApplicationDelegate().listChildrenInstances( this.app.getName(), null, false );
Assert.assertEquals( this.app.getRootInstances().size(), instances.size());
instances = this.client.getApplicationDelegate().listChildrenInstances( this.app.getName(), null, true );
Assert.assertEquals( InstanceHelpers.getAllInstances( this.app ).size(), instances.size());
instances = this.client.getApplicationDelegate().listChildrenInstances( this.app.getName(), InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), false );
Assert.assertEquals( 1, instances.size());
instances = this.client.getApplicationDelegate().listChildrenInstances( this.app.getName(), InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), true );
Assert.assertEquals( 2, instances.size());
}
@Test
public void testListAllComponents() throws Exception {
List<Component> components = this.client.getApplicationDelegate().listAllComponents( "inexisting" );
Assert.assertEquals( 0, components.size());
components = this.client.getApplicationDelegate().listAllComponents( this.app.getName());
Assert.assertEquals( ComponentHelpers.findAllComponents( this.app ).size(), components.size());
}
@Test
public void testFindComponentChildren() throws Exception {
List<Component> components = this.client.getApplicationDelegate().findComponentChildren( "inexisting", "" );
Assert.assertEquals( 0, components.size());
components = this.client.getApplicationDelegate().findComponentChildren( this.app.getName(), "inexisting-component" );
Assert.assertEquals( 0, components.size());
components = this.client.getApplicationDelegate().findComponentChildren( this.app.getName(), null );
Assert.assertEquals( 1, components.size());
Assert.assertTrue( components.contains( this.app.getMySqlVm().getComponent()));
components = this.client.getApplicationDelegate().findComponentChildren( this.app.getName(), this.app.getMySqlVm().getComponent().getName());
Assert.assertEquals( 2, components.size());
Assert.assertTrue( components.contains( this.app.getMySql().getComponent()));;
Assert.assertTrue( components.contains( this.app.getTomcat().getComponent()));;
}
@Test
public void testFindComponentAncestors() throws Exception {
List<Component> components = this.client.getApplicationDelegate().findComponentAncestors( "inexisting", "my-comp" );
Assert.assertEquals( 0, components.size());
components = this.client.getApplicationDelegate().findComponentAncestors( this.app.getName(), "my-comp" );
Assert.assertEquals( 0, components.size());
components = this.client.getApplicationDelegate().findComponentAncestors( this.app.getName(), this.app.getTomcat().getComponent().getName());
Assert.assertEquals( 1, components.size());
Assert.assertTrue( components.contains( this.app.getMySqlVm().getComponent()));
Assert.assertTrue( components.contains( this.app.getTomcatVm().getComponent()));
}
@Test
public void testAddInstance_root_success() throws Exception {
Assert.assertEquals( 2, this.app.getRootInstances().size());
Instance newInstance = new Instance( "vm-mail" ).component( this.app.getMySqlVm().getComponent());
this.client.getApplicationDelegate().addInstance( this.app.getName(), null, newInstance );
Collection<Instance> rootInstances = this.app.getRootInstances();
Assert.assertEquals( 3, rootInstances.size());
for( Instance rootInstance : rootInstances ) {
Assert.assertNotNull( rootInstance.getName(), rootInstance.getComponent());
Assert.assertEquals( rootInstance.getName(), Constants.TARGET_INSTALLER, rootInstance.getComponent().getInstallerName());
}
}
@Test( expected = ApplicationWsException.class )
public void testAddInstance_root_failure() throws Exception {
Assert.assertEquals( 2, this.app.getRootInstances().size());
Instance existingInstance = new Instance( this.app.getMySqlVm().getName());
this.client.getApplicationDelegate().addInstance( this.app.getName(), null, existingInstance );
}
@Test
public void testAddInstance_child_success() throws Exception {
Instance newMysql = new Instance( "mysql-2" ).component( this.app.getMySql().getComponent());
// Override/declare more exports
newMysql.overriddenExports.put("mysql.port", "3307");
newMysql.overriddenExports.put("test", "test");
Assert.assertEquals( 1, this.app.getTomcatVm().getChildren().size());
Assert.assertFalse( this.app.getTomcatVm().getChildren().contains( newMysql ));
this.client.getApplicationDelegate().addInstance( this.app.getName(), InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), newMysql );
Assert.assertEquals( 2, this.app.getTomcatVm().getChildren().size());
List<String> paths = new ArrayList<> ();
for( Instance inst : this.app.getTomcatVm().getChildren()) {
Assert.assertEquals( inst.getName(), "puppet", inst.getComponent().getInstallerName());
paths.add( InstanceHelpers.computeInstancePath( inst ));
}
String rootPath = InstanceHelpers.computeInstancePath( this.app.getTomcatVm());
Assert.assertTrue( paths.contains( rootPath + "/" + newMysql.getName()));
Assert.assertTrue( paths.contains( rootPath + "/" + this.app.getTomcat().getName()));
}
@Test
public void testAddInstance_child_incompleteComponent() throws Exception {
// Pass an incomplete component object to the REST API
String mySqlComponentName = this.app.getMySql().getComponent().getName();
Instance newMysql = new Instance( "mysql-2" ).component( new Component( mySqlComponentName ));
Assert.assertEquals( 1, this.app.getTomcatVm().getChildren().size());
Assert.assertFalse( this.app.getTomcatVm().getChildren().contains( newMysql ));
this.client.getApplicationDelegate().addInstance( this.app.getName(), InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), newMysql );
Assert.assertEquals( 2, this.app.getTomcatVm().getChildren().size());
List<String> paths = new ArrayList<> ();
for( Instance inst : this.app.getTomcatVm().getChildren())
paths.add( InstanceHelpers.computeInstancePath( inst ));
String rootPath = InstanceHelpers.computeInstancePath( this.app.getTomcatVm());
Assert.assertTrue( paths.contains( rootPath + "/" + newMysql.getName()));
Assert.assertTrue( paths.contains( rootPath + "/" + this.app.getTomcat().getName()));
}
@Test( expected = ApplicationWsException.class )
public void testAddInstance_child_failure() throws Exception {
// We cannot deploy a WAR directly on a VM!
// At least, this what the graph says.
Instance newWar = new Instance( "war-2" ).component( this.app.getWar().getComponent());
Assert.assertEquals( 1, this.app.getTomcatVm().getChildren().size());
Assert.assertFalse( this.app.getTomcatVm().getChildren().contains( newWar ));
this.client.getApplicationDelegate().addInstance( this.app.getName(), InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), newWar );
}
@Test( expected = ApplicationWsException.class )
public void testAddInstance_inexstingApplication() throws Exception {
Instance newMysql = new Instance( "mysql-2" ).component( this.app.getMySql().getComponent());
this.client.getApplicationDelegate().addInstance( "inexisting", InstanceHelpers.computeInstancePath( this.app.getTomcatVm()), newMysql );
}
@Test( expected = ApplicationWsException.class )
public void testAddInstance_inexstingParentInstance() throws Exception {
Instance newMysql = new Instance( "mysql-2" ).component( this.app.getMySql().getComponent());
this.client.getApplicationDelegate().addInstance( "inexisting", "/bip/bip", newMysql );
}
@Test
public void testRemoveInstance_success() {
// Check the Tomcat instance is here.
final String tomcatPath = InstanceHelpers.computeInstancePath( this.app.getTomcat() );
Assert.assertNotNull( InstanceHelpers.findInstanceByPath( this.app, tomcatPath ) );
// Delete the Tomcat instance.
this.client.getApplicationDelegate().removeInstance( this.app.getName(), tomcatPath );
// Check it is gone.
Assert.assertNull( InstanceHelpers.findInstanceByPath( this.app, tomcatPath ) );
}
@Test
public void testRemoveInstance_nonExistingInstance() {
try {
this.client.getApplicationDelegate().removeInstance( this.app.getName(), "/I-do-not-exist" );
Assert.fail( "Expecting exception" );
} catch ( UniformInterfaceException e ) {
// Not found!
Assert.assertEquals( 404, e.getResponse().getStatus() );
}
}
@Test
public void testRemoveInstance_nonExistingApplication() {
try {
this.client.getApplicationDelegate().removeInstance( "I-am-not-an-app", InstanceHelpers.computeInstancePath( this.app.getTomcat() ) );
Assert.fail( "Expecting exception" );
} catch ( UniformInterfaceException e ) {
// Not found!
Assert.assertEquals( 404, e.getResponse().getStatus() );
}
}
@Test
public void testResynchronize_success() throws ApplicationWsException {
final Collection<Instance> rootInstances = this.app.getRootInstances();
// Deploy & start everything.
for(Instance i : rootInstances)
i.setStatus( InstanceStatus.DEPLOYED_STARTED );
// Request an application resynchronization.
this.client.getApplicationDelegate().resynchronize( this.app.getName() );
// Check a MsgCmdResynchronize has been sent to each agent.
final List<Message> sentMessages = this.msgClient.allSentMessages;
Assert.assertEquals( rootInstances.size(), sentMessages.size() );
for( Message message : sentMessages )
Assert.assertTrue( message instanceof MsgCmdResynchronize );
}
@Test
public void testResynchronize_nonExistingApplication() {
try {
this.client.getApplicationDelegate().resynchronize( "I-am-not-an-app" );
Assert.fail( "Expecting exception" );
} catch ( UniformInterfaceException e ) {
// Not found!
Assert.assertEquals( 404, e.getResponse().getStatus() );
}
}
@Test( expected = ApplicationWsException.class )
public void testBindApplication_inexistingApplication() throws Exception {
this.client.getApplicationDelegate().bindApplication( "inexisting", this.ma.getApplication().getTemplate().getName(), this.ma.getName());
}
@Test( expected = ApplicationWsException.class )
public void testBindApplication_invalidBoundApplication() throws Exception {
this.client.getApplicationDelegate().bindApplication( this.ma.getName(), this.ma.getApplication().getTemplate().getName(), "invalid" );
}
@Test( expected = ApplicationWsException.class )
public void testBindApplication_invalidBoundTemplate() throws Exception {
TestApplication app2 = new TestApplication();
app2.setDirectory( this.folder.newFolder());
app2.getTemplate().setName( "tpl-other" );
app2.setName( "app-other" );
this.managerWrapper.addManagedApplication( new ManagedApplication( app2 ));
// ma and app2 do not have the same template name
this.client.getApplicationDelegate().bindApplication( this.ma.getName(), this.ma.getApplication().getTemplate().getName(), app2.getName());
}
@Test
public void testBindApplication_success() throws Exception {
// Create a second application with a different template
TestApplication app2 = new TestApplication();
app2.setDirectory( this.folder.newFolder());
app2.getTemplate().setName( "tpl-other" );
app2.getTemplate().setExternalExportsPrefix( "eep" );
app2.setName( "app-other" );
this.managerWrapper.addManagedApplication( new ManagedApplication( app2 ));
// Bind and check
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getTomcatVm()).size());
Assert.assertEquals( 0, this.ma.removeAwaitingMessages( this.app.getMySqlVm()).size());
this.client.getApplicationDelegate().bindApplication( this.ma.getName(), app2.getTemplate().getExternalExportsPrefix(), app2.getName());
Assert.assertEquals( 0, this.msgClient.allSentMessages.size());
List<Message> messages = this.ma.removeAwaitingMessages( this.app.getTomcatVm());
Assert.assertEquals( 1, messages.size());
messages.addAll( this.ma.removeAwaitingMessages( this.app.getMySqlVm()));
Assert.assertEquals( 2, messages.size());
for( Message m : this.msgClient.allSentMessages ) {
Assert.assertEquals( MsgCmdChangeBinding.class, m.getClass());
MsgCmdChangeBinding msg = (MsgCmdChangeBinding) m;
Assert.assertEquals( app2.getTemplate().getExternalExportsPrefix(), msg.getExternalExportsPrefix());
Assert.assertNotNull( msg.getAppNames());
Assert.assertEquals( 1, msg.getAppNames().size());
Assert.assertTrue( msg.getAppNames().contains( app2.getName()));
}
}
@Test
public void testListAllCommands() throws Exception {
List<String> cmds = this.client.getApplicationDelegate().listAllCommands( this.app.getName());
Assert.assertEquals( 0, cmds.size());
File cmdFile = new File( this.app.getDirectory(), Constants.PROJECT_DIR_COMMANDS + "/cmd" + Constants.FILE_EXT_COMMANDS );
Assert.assertTrue( cmdFile.getParentFile().mkdirs());
Utils.writeStringInto( "write this into /tmp", cmdFile );
cmds = this.client.getApplicationDelegate().listAllCommands( this.app.getName());
Assert.assertEquals( 1, cmds.size());
Assert.assertEquals( "cmd", cmds.get( 0 ));
}
}