@Test
  public void testSetAdminGroupsSuccess() throws Exception {
    Task task = new Task();
    task.setId(taskId);

    when(deploymentFeClient.setSecurityGroups(eq(deploymentId), anyListOf(String.class)))
        .thenReturn(task);

    ResourceList<String> adminGroups =
        new ResourceList<>(
            Arrays.asList(new String[] {"tenant\\adminGroup1", "tenant\\adminGroup2"}));

    Response response =
        client()
            .target(deploymentRoutePath)
            .request()
            .post(Entity.entity(adminGroups, MediaType.APPLICATION_JSON_TYPE));

    assertThat(response.getStatus(), is(200));

    Task responseTask = response.readEntity(Task.class);
    assertThat(responseTask, is(task));
    assertThat(new URI(responseTask.getSelfLink()).isAbsolute(), is(true));
    assertThat(responseTask.getSelfLink().endsWith(taskRoutePath), is(true));
  }
  /**
   * This method extracts the error strings associated with one or more failed task steps from a
   * Task object.
   *
   * @param task Supplies a task in the ERROR state.
   * @return A list of task step errors in a form suitable for use in creating an exception.
   */
  public static String getErrors(Task task) {
    if (!task.getState().toUpperCase().equals("ERROR")) {
      throw new IllegalArgumentException("task");
    }

    List<String> errorList = new ArrayList<>();
    for (Step step : task.getSteps()) {
      if (step.getState().toUpperCase().equals("ERROR")) {
        for (ApiError apiError : step.getErrors()) {
          errorList.add(
              String.format(
                  "Task \"%s\": step \"%s\" failed with error code \"%s\", message \"%s\"",
                  task.getOperation(),
                  step.getOperation(),
                  apiError.getCode(),
                  apiError.getMessage()));
        }
      }
    }

    if (0 == errorList.size()) {
      throw new RuntimeException("Task in error state contains no failed steps");
    }

    return errorList.toString();
  }
  /**
   * This method polls the task status asynchronously until the task completes or fails.
   *
   * @param task Supplies the task object.
   * @param client Supplies the API client object.
   * @param service Supplies the DCP micro-service which is waiting on the task completion.
   * @param queryTaskInterval Supplies the time interval between the task status query.
   * @param callback Supplies the callback to be invoked when the task completes or fails.
   */
  public static void pollTaskAsync(
      final Task task,
      final ApiClient client,
      final Service service,
      final int queryTaskInterval,
      final FutureCallback<Task> callback) {

    switch (task.getState().toUpperCase()) {
      case "QUEUED":
      case "STARTED":
        Runnable runnable =
            new Runnable() {
              @Override
              public void run() {
                try {
                  ServiceUtils.logInfo(
                      service, "Calling GetTask API on with task ID %s", task.getId());

                  client
                      .getTasksApi()
                      .getTaskAsync(
                          task.getId(),
                          new FutureCallback<Task>() {
                            @Override
                            public void onSuccess(Task result) {
                              ServiceUtils.logInfo(
                                  service, "GetTask API call returned task %s", result.toString());
                              try {
                                pollTaskAsync(result, client, service, queryTaskInterval, callback);
                              } catch (Throwable throwable) {
                                callback.onFailure(throwable);
                              }
                            }

                            @Override
                            public void onFailure(Throwable t) {
                              callback.onFailure(t);
                            }
                          });
                } catch (Throwable t) {
                  callback.onFailure(t);
                }
              }
            };

        service.getHost().schedule(runnable, queryTaskInterval, TimeUnit.MILLISECONDS);
        break;
      case "ERROR":
        callback.onFailure(new RuntimeException(ApiUtils.getErrors(task)));
        break;
      case "COMPLETED":
        callback.onSuccess(task);
        break;
      default:
        callback.onFailure(new RuntimeException("Unknown task state: " + task.getState()));
        break;
    }
  }
 /**
  * This method is the completion handler for the setMetadataTask.
  *
  * @param currentState Supplies the current state object.
  * @param task Supplies the task object.
  */
 private void processSetMetadataTask(final State currentState, final Task task) {
   switch (task.getState().toUpperCase()) {
     case "QUEUED":
     case "STARTED":
       scheduleSetMetadataTaskCall(this, currentState, task.getId());
       break;
     case "ERROR":
       throw new RuntimeException(ApiUtils.getErrors(task));
     case "COMPLETED":
       TaskUtils.sendSelfPatch(this, buildPatch(TaskState.TaskStage.FINISHED, (Throwable) null));
       break;
     default:
       throw new RuntimeException("Unknown task state: " + task.getState());
   }
 }
  @Test(dataProvider = "pageSizes")
  public void testGetResourceTicketTasks(
      Optional<Integer> pageSize, List<Task> expectedTasks, List<String> expectedTaskRoutes)
      throws Exception {
    task1.setId(taskId1);
    task2.setId(taskId2);

    when(client.getResourceTicketTasks(
            ticketId,
            Optional.<String>absent(),
            Optional.of(PaginationConfig.DEFAULT_DEFAULT_PAGE_SIZE)))
        .thenReturn(new ResourceList<>(ImmutableList.of(task1, task2), null, null));
    when(client.getResourceTicketTasks(ticketId, Optional.<String>absent(), Optional.of(1)))
        .thenReturn(
            new ResourceList<>(ImmutableList.of(task1), UUID.randomUUID().toString(), null));
    when(client.getResourceTicketTasks(ticketId, Optional.<String>absent(), Optional.of(2)))
        .thenReturn(new ResourceList<>(ImmutableList.of(task1, task2), null, null));
    when(client.getResourceTicketTasks(ticketId, Optional.<String>absent(), Optional.of(3)))
        .thenReturn(new ResourceList<>(Collections.emptyList(), null, null));

    Response response = getTasks(pageSize);
    assertThat(response.getStatus(), is(200));

    ResourceList<Task> tasks = response.readEntity(new GenericType<ResourceList<Task>>() {});

    assertThat(tasks.getItems().size(), is(expectedTasks.size()));

    for (int i = 0; i < tasks.getItems().size(); i++) {
      assertThat(tasks.getItems().get(i), is(expectedTasks.get(i)));
      assertThat(
          new URI(tasks.getItems().get(i).getSelfLink()).isAbsolute(), CoreMatchers.is(true));
      assertThat(
          tasks.getItems().get(i).getSelfLink().endsWith(expectedTaskRoutes.get(i)),
          CoreMatchers.is(true));
    }

    verifyPageLinks(tasks);
  }
    @SuppressWarnings({"rawtypes", "unchecked"})
    private void mockApiClient(boolean isSuccess) throws Throwable {

      ApiClient apiClient = mock(ApiClient.class);
      DeploymentApi deploymentApi = mock(DeploymentApi.class);
      VmApi vmApi = mock(VmApi.class);
      TasksApi tasksApi = mock(TasksApi.class);

      Deployment deployment = new Deployment();
      deployment.setId("deploymentId1");
      deployment.setAuth(new AuthInfo());
      final ResourceList<Deployment> deploymentResourceList =
          new ResourceList<>(Arrays.asList(deployment));

      Vm vm1 = new Vm();
      vm1.setId("vm1");
      Map<String, String> metadata = new HashMap<String, String>();
      metadata.put("key1", ContainersConfig.ContainerType.Zookeeper.name());
      vm1.setMetadata(metadata);
      final ResourceList<Vm> vmList = new ResourceList<>(Arrays.asList(vm1));

      NetworkConnection networkConnection = new NetworkConnection();
      networkConnection.setNetwork("VM VLAN");
      networkConnection.setIpAddress("127.0.0.1");

      VmNetworks vmNetworks = new VmNetworks();
      vmNetworks.setNetworkConnections(Collections.singleton(networkConnection));

      final Task getNetworksTaskResult = new Task();
      getNetworksTaskResult.setId("taskId");
      getNetworksTaskResult.setState("COMPLETED");
      getNetworksTaskResult.setResourceProperties(vmNetworks);

      final Task taskReturnedByPauseSystem = TestHelper.createCompletedApifeTask("PAUSE_SYSTEM");

      if (isSuccess) {
        // List all deployments
        doAnswer(
                new Answer() {
                  @Override
                  public Object answer(InvocationOnMock invocation) throws Throwable {
                    ((FutureCallback<ResourceList<Deployment>>) invocation.getArguments()[0])
                        .onSuccess(deploymentResourceList);
                    return null;
                  }
                })
            .when(deploymentApi)
            .listAllAsync(any(FutureCallback.class));

        // Pause system
        doAnswer(
                new Answer() {
                  @Override
                  public Object answer(InvocationOnMock invocation) throws Throwable {
                    ((FutureCallback<Task>) invocation.getArguments()[1])
                        .onSuccess(taskReturnedByPauseSystem);
                    return null;
                  }
                })
            .when(deploymentApi)
            .pauseSystemAsync(any(String.class), any(FutureCallback.class));

        // List all vms
        doAnswer(
                new Answer() {
                  @Override
                  public Object answer(InvocationOnMock invocation) throws Throwable {
                    ((FutureCallback<ResourceList<Vm>>) invocation.getArguments()[1])
                        .onSuccess(vmList);
                    return null;
                  }
                })
            .when(deploymentApi)
            .getAllDeploymentVmsAsync(anyString(), any(FutureCallback.class));

        // Get vm networks
        doAnswer(
                new Answer() {
                  @Override
                  public Object answer(InvocationOnMock invocation) throws Throwable {
                    ((FutureCallback<Task>) invocation.getArguments()[1])
                        .onSuccess(getNetworksTaskResult);
                    return null;
                  }
                })
            .when(vmApi)
            .getNetworksAsync(any(String.class), any(FutureCallback.class));

      } else {
        doAnswer(
                new Answer() {
                  @Override
                  public Object answer(InvocationOnMock invocation) throws Throwable {
                    ((FutureCallback<ResourceList<Deployment>>) invocation.getArguments()[0])
                        .onFailure(new Exception("failed!"));
                    return null;
                  }
                })
            .when(deploymentApi)
            .listAllAsync(any(FutureCallback.class));
      }

      doReturn(deploymentApi).when(apiClient).getDeploymentApi();
      doReturn(vmApi).when(apiClient).getVmApi();
      doReturn(tasksApi).when(apiClient).getTasksApi();
      doReturn(apiClient).when(apiClientFactory).create();
      doReturn(apiClient).when(apiClientFactory).create(any(String.class));
    }