@Override
    public void setApplicationState(OrchestratorContext context, ApplicationInstanceId applicationId,
                                    ClusterControllerNodeState wantedState) throws ApplicationStateChangeDeniedException {
        try {
            ClusterControllerClientTimeouts timeouts = context.getClusterControllerTimeouts();
            Inspector response = client.send(strategy(hosts), Method.POST)
                                       .at("cluster", "v2", clusterName)
                                       .deadline(timeouts.readBudget())
                                       .parameters(() -> deadline(timeouts))
                                       .body(stateChangeRequestBytes(wantedState, Condition.FORCE, false))
                                       .throwing(retryOnRedirect)
                                       .read(SlimeUtils::jsonToSlime).get();
            if ( ! response.field("wasModified").asBool()) {
                throw new ApplicationStateChangeDeniedException("Failed to set application " + applicationId + ", cluster name " +
                                                                clusterName + " to cluster state " + wantedState + " due to: " +
                                                                response.field("reason").asString());
            }
        }
        catch (ResponseException e) {
            throw new ApplicationStateChangeDeniedException("Failed to set application " + applicationId + " cluster name " +
                                                            clusterName + " to cluster state " + wantedState + " due to: " + e.getMessage());
        }
        catch (UncheckedIOException e) {
            throw new ApplicationStateChangeDeniedException("Failed communicating with cluster controllers " + hosts +
                                                            " with cluster ID " + clusterName + ": " + e.getCause().getMessage());
        }
        catch (UncheckedTimeoutException e) {
            throw new ApplicationStateChangeDeniedException("Timed out while waiting for cluster controllers " + hosts +
                                                            " with cluster ID " + clusterName + ": " + e.getMessage());
        }
    }
@Test
    public void verifySetApplicationState() {
        wire.expect((url, body) -> {
                        assertEquals("http://host1:19050/cluster/v2/cc?timeout=299.6",
                                     url.asURI().toString());
                        assertEquals("{\"state\":{\"user\":{\"reason\":\"Orchestrator\",\"state\":\"up\"}},\"condition\":\"FORCE\"}",
                                     body);
                        return "{ \"message\": \":<\" }";
                    },
                    500);
        assertEquals("Failed to set application app cluster name cc to cluster state UP due to: " +
                     "got status code 500 for POST http://host1:19050/cluster/v2/cc?timeout=299.6: :<",
                     assertThrows(ApplicationStateChangeDeniedException.class,
                                  () -> client.setApplicationState(OrchestratorContext.createContextForAdminOp(clock),
                                                                   new ApplicationInstanceId("app"),
                                                                   UP))
                             .getMessage());
    }