public void testSingleModuleUpdateExternalCreation() throws Exception {

    String prefix = "testSingleModuleUpdateExternalCreation";
    String appName = harness.getDefaultWebAppName(prefix);

    // After deployment the module must exist and be mapped to an existing
    // CloudApplication
    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(appName);
    assertNull(appModule);

    appModule = serverBehavior.updateCloudModule(appName, new NullProgressMonitor());
    assertNull(appModule);

    // Create separate external client
    CloudFoundryOperations client = harness.createExternalClient();
    client.login();

    List<String> urls = new ArrayList<String>();
    urls.add(harness.getExpectedDefaultURL(prefix));
    client.createApplication(
        appName, new Staging(), CloudUtil.DEFAULT_MEMORY, urls, new ArrayList<String>());

    appModule = serverBehavior.updateCloudModule(appName, new NullProgressMonitor());

    assertEquals(appName, appModule.getDeployedApplicationName());
    assertEquals(appModule.getDeployedApplicationName(), appModule.getApplication().getName());
    assertEquals(CloudUtil.DEFAULT_MEMORY, appModule.getApplication().getMemory());
    assertEquals(appModule.getDeploymentInfo().getMemory(), appModule.getApplication().getMemory());
  }
  public void testUpdateModulesServerBehaviourWrongCloudApp() throws Exception {
    // Update modules API in behaviour will return a
    // CloudFoundryApplicationModule for an existing Cloud application in
    // the Cloud Space. This associated update modules for the Cloud Foundry
    // Server
    // which the behaviour uses is tested separately in a different test
    // case
    String prefix = "testUpdateModulesServerBehaviourWrongCloudApp";
    String expectedAppName = harness.getDefaultWebAppName(prefix);

    // Create the app externally AFTER the server connects in the setup to
    // ensure the tools did not pick up the Cloud application during refresh
    CloudFoundryOperations client = harness.createExternalClient();
    client.login();

    List<String> urls = new ArrayList<String>();
    urls.add(harness.getExpectedDefaultURL(prefix));
    client.createApplication(
        expectedAppName, new Staging(), CloudUtil.DEFAULT_MEMORY, urls, new ArrayList<String>());

    // The tool has not refreshed after the app was created with an external
    // client, so there should be no module
    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(expectedAppName);
    assertNull(appModule);

    CloudFoundryApplicationModule wrongModule =
        serverBehavior.updateCloudModule("wrongApp", new NullProgressMonitor());
    assertNull(wrongModule);

    wrongModule =
        serverBehavior.updateCloudModuleWithInstances("wrongApp", new NullProgressMonitor());
    assertNull(wrongModule);
  }
  public void testUpdateModuleInstances() throws Exception {
    // Update modules API in behaviour will return a
    // CloudFoundryApplicationModule for an existing Cloud application in
    // the Cloud Space. This associated update modules for the Cloud Foundry
    // Server
    // which the behaviour uses is tested separately in a different test
    // case

    String prefix = "testUpdateModuleInstances";
    String expectedAppName = harness.getDefaultWebAppName(prefix);

    // Create the app externally AFTER the server connects in the setup to
    // ensure the tools did not pick up the Cloud application during refresh
    CloudFoundryOperations client = harness.createExternalClient();
    client.login();

    List<String> urls = new ArrayList<String>();
    urls.add(harness.getExpectedDefaultURL(prefix));
    client.createApplication(
        expectedAppName, new Staging(), CloudUtil.DEFAULT_MEMORY, urls, new ArrayList<String>());

    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(expectedAppName);
    // Tooling has not yet been updated so there is no corresponding
    // appModule even though the app exists in the Cloud space
    assertNull(appModule);

    // This will tell the behaviour to fetch the Cloud application from the
    // Cloud space and generate a module
    CloudFoundryApplicationModule updateModule =
        serverBehavior.updateCloudModuleWithInstances(expectedAppName, new NullProgressMonitor());
    assertEquals(expectedAppName, updateModule.getDeployedApplicationName());
    assertEquals(
        updateModule.getDeployedApplicationName(), updateModule.getApplication().getName());

    // Check the mapping is correct
    assertEquals(updateModule.getName(), updateModule.getApplication().getName());
    assertEquals(CloudUtil.DEFAULT_MEMORY, updateModule.getApplication().getMemory());
    assertEquals(
        updateModule.getDeploymentInfo().getMemory(), updateModule.getApplication().getMemory());
    assertEquals(1, updateModule.getInstanceCount());

    // There is one instance, but since the app was created EXTERNALLY and
    // not started, there should
    // be no instance info
    assertEquals(0, updateModule.getApplicationStats().getRecords().size());
    assertNull(updateModule.getInstancesInfo());

    updateModule =
        serverBehavior.updateCloudModuleWithInstances((String) null, new NullProgressMonitor());
    assertNull(updateModule);

    updateModule =
        serverBehavior.updateCloudModuleWithInstances("wrongName", new NullProgressMonitor());
    assertNull(updateModule);

    updateModule =
        serverBehavior.updateCloudModuleWithInstances((IModule) null, new NullProgressMonitor());
    assertNull(updateModule);
  }
  public void testAllModuleUpdateExternalAppDeletion() throws Exception {

    String prefix = "testAllModuleUpdateExternalAppDeletion";
    String appName = harness.getDefaultWebAppName(prefix);
    IProject project = createWebApplicationProject();

    boolean stopMode = false;

    // Configure the test fixture for deployment.
    // This step is a substitute for the Application deployment wizard
    getTestFixture().configureForApplicationDeployment(appName, CloudUtil.DEFAULT_MEMORY, stopMode);

    IModule module = getModule(project.getName());

    // Push the application.
    cloudServer
        .getBehaviour()
        .operations()
        .applicationDeployment(new IModule[] {module}, ApplicationAction.PUSH)
        .run(new NullProgressMonitor());

    // After deployment the module must exist and be mapped to an existing
    // CloudApplication
    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(appName);

    // Verify the module exists
    assertEquals(appModule.getDeployedApplicationName(), appModule.getApplication().getName());

    // Delete module externally and verify that module refresh picks up the
    // change

    // Create separate external client
    CloudFoundryOperations client = harness.createExternalClient();
    client.login();
    client.deleteApplication(appName);

    // Update through all-modules update, and also verify existing modules
    // matches results
    Map<String, CloudApplication> allApps = new HashMap<String, CloudApplication>();
    cloudServer.updateModules(allApps);

    appModule = cloudServer.getExistingCloudModule(appName);
    assertNull(appModule);

    // Update through single-module update, and also verify that existing
    // modules matches the results
    appModule = serverBehavior.updateCloudModule(appName, new NullProgressMonitor());
    assertNull(appModule);

    appModule = cloudServer.getExistingCloudModule(appName);
    assertNull(appModule);
  }
  public void testModuleRefreshDuringServerConnect2() throws Exception {
    // Deploy and start an application.
    // Disconnect through the server behaviour. Verify through an external
    // client that the app
    // remains deployed and in started mode.
    // Reconnect, and verify that the application is still running (i.e.
    // disconnecting
    // the server should not stop the application).

    String appPrefix = "testModuleRefreshDuringServerConnect2";
    String expectedAppName = harness.getDefaultWebAppName(appPrefix);

    createWebApplicationProject();

    // Note that deploying application fires off an app change event AFTER
    // the deployment is
    // successful. To make sure that the second event listener further down
    // does not accidentally receive the app
    // change event,
    // wait for the app change event from the deploy first, and then
    // schedule the second listener to
    // listen to the expected refresh event
    deployAndWaitForDeploymentEvent(appPrefix);

    // Cloud module should have been created.
    Collection<CloudFoundryApplicationModule> appModules = cloudServer.getExistingCloudModules();
    assertEquals(
        harness.getDefaultWebAppName(appPrefix),
        appModules.iterator().next().getDeployedApplicationName());

    // Disconnect and verify that there are no cloud foundry application
    // modules
    serverBehavior.disconnect(new NullProgressMonitor());
    appModules = cloudServer.getExistingCloudModules();
    assertTrue(
        "Expected empty list of cloud application modules after server disconnect",
        appModules.isEmpty());

    // Now create an external client to independently check that the
    // application remains deployed and in started mode

    CloudFoundryOperations client = harness.createExternalClient();
    client.login();
    List<CloudApplication> deployedApplications = client.getApplications();
    assertEquals(
        "Expected 1 Cloud application in Cloud space after server disconnect",
        1,
        deployedApplications.size());
    assertEquals(expectedAppName, deployedApplications.get(0).getName());
    assertTrue(deployedApplications.get(0).getState() == AppState.STARTED);

    // Register a module refresh listener before connecting again to be
    // notified when
    // modules are refreshed
    ModulesRefreshListener listener =
        getModulesRefreshListener(null, cloudServer, CloudServerEvent.EVENT_SERVER_REFRESHED);

    serverBehavior.connect(new NullProgressMonitor());

    assertModuleRefreshedAndDispose(listener, CloudServerEvent.EVENT_SERVER_REFRESHED);

    appModules = cloudServer.getExistingCloudModules();
    CloudFoundryApplicationModule appModule = appModules.iterator().next();

    assertEquals(expectedAppName, appModule.getDeployedApplicationName());

    assertApplicationIsRunning(appModule);
  }
  public void testModuleUpdatesExternalChanges() throws Exception {

    // Tests various module update scenarios due to external changes.
    // This is performed in one test to avoid multiple application creations
    // and deployments during junit setups which are slow
    // Tests the following cases:
    // 1. Push application for the first time - Module should be created and
    // mapped to a CloudApplication
    // 2. Update the application externally and update through behaviour API
    // - Module and mapping to CloudApplication should be updated
    // 3. Update the application externally and refresh all Modules - Module
    // and mapping to CloudApplication should be updated.

    String prefix = "testModuleUpdatesExternalChanges";
    String appName = harness.getDefaultWebAppName(prefix);
    IProject project = createWebApplicationProject();

    boolean stopMode = false;

    // Configure the test fixture for deployment.
    // This step is a substitute for the Application deployment wizard
    getTestFixture().configureForApplicationDeployment(appName, CloudUtil.DEFAULT_MEMORY, stopMode);

    IModule module = getModule(project.getName());

    // Push the application
    cloudServer
        .getBehaviour()
        .operations()
        .applicationDeployment(new IModule[] {module}, ApplicationAction.PUSH)
        .run(new NullProgressMonitor());

    // After deployment the module must exist and be mapped to an existing
    // CloudApplication
    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(appName);

    assertNotNull(appModule);
    // Test that the mapping to the actual application in the Cloud space is
    // present. Since a
    // CloudApplication is not created by the underlying client unless it
    // exists, this also
    // indirectly tests that the CloudApplication was successfully created
    // indicating the application
    // exists in the Cloud space.
    assertNotNull(appModule.getApplication());
    assertEquals(appModule.getDeployedApplicationName(), appModule.getApplication().getName());

    // To test update on external changes, verify the current memory
    assertEquals(CloudUtil.DEFAULT_MEMORY, appModule.getDeploymentInfo().getMemory());

    // Verify that the CloudApplication in the Cloud space exists through
    // the list of all CloudApplications
    List<CloudApplication> applications = serverBehavior.getApplications(new NullProgressMonitor());
    boolean found = false;

    for (CloudApplication application : applications) {
      if (application.getName().equals(appName)) {
        found = true;
        break;
      }
    }
    assertTrue("Expected CloudApplication for " + appName + " to exist in the Cloud space", found);

    // Now modify the application externally and verify that when performing
    // a module update
    // that the new changes are picked up by the tooling

    // Create separate external client
    CloudFoundryOperations externalClient = harness.createExternalClient();
    externalClient.login();

    // Refresh Module through behaviour to check if it picks up changes

    // 1. Test via single-module update
    externalClient.updateApplicationMemory(appName, 737);
    CloudApplication updatedCloudApplicationFromClient = externalClient.getApplication(appName);

    appModule = serverBehavior.updateCloudModule(appName, new NullProgressMonitor());

    assertEquals(appName, appModule.getDeployedApplicationName());
    assertEquals(
        appModule.getDeployedApplicationName(), updatedCloudApplicationFromClient.getName());
    assertEquals(737, updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getApplication().getMemory(), updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getDeploymentInfo().getMemory(), updatedCloudApplicationFromClient.getMemory());

    // 2. Test via single-module update and it's instances
    externalClient.updateApplicationMemory(appName, 555);

    updatedCloudApplicationFromClient = externalClient.getApplication(appName);
    appModule = serverBehavior.updateCloudModuleWithInstances(appName, new NullProgressMonitor());

    assertEquals(appName, appModule.getDeployedApplicationName());
    assertEquals(
        appModule.getDeployedApplicationName(), updatedCloudApplicationFromClient.getName());

    assertEquals(
        appModule.getDeployedApplicationName(), updatedCloudApplicationFromClient.getName());
    assertEquals(555, updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getApplication().getMemory(), updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getDeploymentInfo().getMemory(), updatedCloudApplicationFromClient.getMemory());

    // 3. Test via module refresh of all modules
    externalClient.updateApplicationMemory(appName, 345);
    updatedCloudApplicationFromClient = externalClient.getApplication(appName);
    Map<String, CloudApplication> allApps = new HashMap<String, CloudApplication>();
    allApps.put(updatedCloudApplicationFromClient.getName(), updatedCloudApplicationFromClient);

    cloudServer.updateModules(allApps);

    appModule = cloudServer.getExistingCloudModule(appName);

    assertEquals(appName, appModule.getDeployedApplicationName());
    assertEquals(
        appModule.getDeployedApplicationName(), updatedCloudApplicationFromClient.getName());

    assertEquals(
        appModule.getDeployedApplicationName(), updatedCloudApplicationFromClient.getName());
    assertEquals(345, updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getApplication().getMemory(), updatedCloudApplicationFromClient.getMemory());
    assertEquals(
        appModule.getDeploymentInfo().getMemory(), updatedCloudApplicationFromClient.getMemory());
  }
  public void testUpdateModulesCloudServer() throws Exception {

    // Tests the Update modules API in the server that will CREATE or return
    // an existing
    // CloudFoundryApplicationModule ONLY if it is given a CloudApplication.

    String prefix = "testUpdateModulesCloudServer";
    String expectedAppName = harness.getDefaultWebAppName(prefix);

    // Create the app externally AFTER the server connects in the setup to
    // ensure the tools did not pick up the Cloud application during refresh
    CloudFoundryOperations client = harness.createExternalClient();
    client.login();

    List<String> urls = new ArrayList<String>();
    urls.add(harness.getExpectedDefaultURL(prefix));
    client.createApplication(
        expectedAppName, new Staging(), CloudUtil.DEFAULT_MEMORY, urls, new ArrayList<String>());

    CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule(expectedAppName);
    // Tooling has not yet been updated so there is no corresponding
    // appModule even though the app exists in the Cloud space
    assertNull(appModule);

    // No actual cloud application passed to update therefore no associated
    // CloudFoundryApplicationModule should be found
    appModule = cloudServer.updateModule(null, expectedAppName, new NullProgressMonitor());
    assertNull(appModule);

    appModule = cloudServer.updateModule(null, null, new NullProgressMonitor());
    assertNull(appModule);

    assertTrue(cloudServer.getExistingCloudModules().isEmpty());

    // Get the actual cloud app directly from the Cloud space
    CloudApplication actualApp = client.getApplications().get(0);

    // Now create the CloudFoundryApplicationModule
    appModule = cloudServer.updateModule(actualApp, expectedAppName, new NullProgressMonitor());

    assertEquals(expectedAppName, appModule.getDeployedApplicationName());
    assertEquals(appModule.getDeployedApplicationName(), appModule.getApplication().getName());

    // Check the mapping is correct
    assertEquals(actualApp.getName(), appModule.getApplication().getName());

    assertEquals(CloudUtil.DEFAULT_MEMORY, appModule.getApplication().getMemory());
    assertEquals(appModule.getDeploymentInfo().getMemory(), appModule.getApplication().getMemory());

    // It should match what is obtained through getExisting API
    CloudFoundryApplicationModule existingCloudMod =
        cloudServer.getExistingCloudModule(expectedAppName);

    assertEquals(expectedAppName, existingCloudMod.getDeployedApplicationName());
    assertEquals(
        existingCloudMod.getDeployedApplicationName(), existingCloudMod.getApplication().getName());

    // Check the mapping is correct
    assertEquals(actualApp.getName(), existingCloudMod.getApplication().getName());

    assertEquals(CloudUtil.DEFAULT_MEMORY, existingCloudMod.getApplication().getMemory());
    assertEquals(
        existingCloudMod.getDeploymentInfo().getMemory(),
        existingCloudMod.getApplication().getMemory());

    // Check the other existing Modules API
    CloudFoundryApplicationModule sameExistingApp =
        cloudServer.getExistingCloudModules().iterator().next();
    assertEquals(expectedAppName, sameExistingApp.getDeployedApplicationName());
    assertEquals(
        sameExistingApp.getDeployedApplicationName(), sameExistingApp.getApplication().getName());

    // Check the mapping is correct
    assertEquals(actualApp.getName(), sameExistingApp.getApplication().getName());

    assertEquals(CloudUtil.DEFAULT_MEMORY, sameExistingApp.getApplication().getMemory());
    assertEquals(
        sameExistingApp.getDeploymentInfo().getMemory(),
        sameExistingApp.getApplication().getMemory());
  }
  @Override
  protected void pushApplication(
      CloudFoundryOperations client,
      final CloudFoundryApplicationModule appModule,
      ApplicationArchive applicationArchive,
      final IProgressMonitor monitor)
      throws CoreException {
    String appName = appModule.getDeploymentInfo().getDeploymentName();

    CloudApplication existingApp = null;

    try {
      existingApp = getBehaviour().getCloudApplication(appName, monitor);
    } catch (CoreException ce) {
      if (!CloudErrorUtil.isNotFoundException(ce)) {
        throw ce;
      }
    }

    // Create the application if it doesn't already exist
    if (existingApp == null) {
      String creatingAppLabel = NLS.bind(Messages.CONSOLE_APP_CREATION, appName);
      getBehaviour().printlnToConsole(appModule, creatingAppLabel);

      // BUG - [87862532]: Fetch all the information BEFORE
      // creating the application. The reason for this
      // is to prevent any other operation that updates the module from
      // clearing the deploymentinfo after the application is created
      // but before other properties are updated like environment
      // variables
      // and instances
      Staging staging = appModule.getDeploymentInfo().getStaging();
      List<String> uris =
          appModule.getDeploymentInfo().getUris() != null
              ? appModule.getDeploymentInfo().getUris()
              : new ArrayList<String>(0);
      List<String> services = appModule.getDeploymentInfo().asServiceBindingList();
      List<EnvironmentVariable> variables = appModule.getDeploymentInfo().getEnvVariables();
      int instances = appModule.getDeploymentInfo().getInstances();

      if (staging == null) {
        // For v2, a non-null staging is required.
        staging = new Staging();
      }
      CoreException cloudAppCreationClientError = null;

      // Guard against host taken errors and other errors that may
      // create the app but
      // prevent further deployment. If the app was still created
      // attempt to set env vars and instaces
      SubMonitor subMonitor = SubMonitor.convert(monitor, 50);
      subMonitor.subTask(creatingAppLabel);
      try {
        client.createApplication(
            appName, staging, appModule.getDeploymentInfo().getMemory(), uris, services);
      } catch (Exception e) {
        String hostTaken = CloudErrorUtil.getHostTakenError(e);
        if (hostTaken != null) {
          cloudAppCreationClientError = CloudErrorUtil.toCoreException(hostTaken);
        } else {
          cloudAppCreationClientError = CloudErrorUtil.toCoreException(e);
        }
      }

      subMonitor.worked(30);

      // [87881946] - Try setting the env vars and instances even if an
      // error was thrown while creating the application
      // as the application may still have been created in the Cloud space
      // in spite of the error
      try {
        CloudApplication actualApp =
            getBehaviour().getCloudApplication(appName, subMonitor.newChild(20));

        if (actualApp != null) {
          SubMonitor updateMonitor = SubMonitor.convert(subMonitor, 100);
          getBehaviour()
              .getRequestFactory()
              .getUpdateEnvVarRequest(appName, variables)
              .run(updateMonitor.newChild(50));

          // Update instances if it is more than 1. By default, app
          // starts
          // with 1 instance.

          if (instances > 1) {
            getBehaviour()
                .updateApplicationInstances(appName, instances, updateMonitor.newChild(50));
          } else {
            updateMonitor.worked(50);
          }
        }
      } catch (CoreException ce) {
        if (cloudAppCreationClientError == null) {
          throw ce;
        }
      }

      // Even if application was created in the Cloud space, and env vars
      // and instances set, if an exception
      // was thrown while creating the client, throw it
      if (cloudAppCreationClientError != null) {
        throw cloudAppCreationClientError;
      }
    }
    super.pushApplication(client, appModule, applicationArchive, monitor);
  }