@Test
  public void testErrorSearchRdfWithoutAuthentication() throws Exception {
    // prepare:
    final InferredOWLOntologyID testArtifact =
        this.loadTestArtifact(
            TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);

    final ClientResource searchClientResource =
        new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));

    // request without authentication
    try {
      searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCHTERM, "Scan");
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, testArtifact.getOntologyIRI().toString());
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_SEARCH_TYPES, "http://purl.org/podd/ns/poddScience#Platform");

      searchClientResource.get(MediaType.APPLICATION_RDF_XML);
      Assert.fail("Should have thrown a ResourceException");
    } catch (final ResourceException e) {
      Assert.assertEquals(Status.CLIENT_ERROR_UNAUTHORIZED, e.getStatus());
    } finally {
      this.releaseClient(searchClientResource);
    }
  }
  public GetStreamKeyStreamServer getGetStreamKeyStreamServer(
      String songID, GetCountry country, String sesionID) {
    GetStreamKeyStreamServer res = null;
    String post =
        "{\"method\":\"getStreamKeyStreamServer\",\"header\":{\"wsKey\":\""
            + KEY
            + "\",\"sessionID\":\""
            + sesionID
            + "\"},\"parameters\":{\"songID\":\""
            + songID
            + "\",\"country\":"
            + country.getResult()
            + ",\"lowBitrate\":\"\"}}";
    ClientResource cr = new ClientResource(uri + getSignatures(post));
    try {
      res = gson.fromJson(cr.post(post).getText(), GetStreamKeyStreamServer.class);
    } catch (JsonSyntaxException e) {
      e.printStackTrace();
    } catch (ResourceException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return res;
  }
  @Test
  public void testErrorSearchRdfWithoutSearchTerm() throws Exception {
    // prepare:
    final InferredOWLOntologyID testArtifact =
        this.loadTestArtifact(
            TestConstants.TEST_ARTIFACT_20130206, MediaType.APPLICATION_RDF_TURTLE);

    final ClientResource searchClientResource =
        new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));

    // there is no need to authenticate or have a test artifact as the
    // search term is checked
    // for first
    try {
      // no search term!
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, testArtifact.getOntologyIRI().toString());
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_SEARCH_TYPES, "http://purl.org/podd/ns/poddScience#Platform");

      searchClientResource.get(MediaType.APPLICATION_RDF_XML);
      Assert.fail("Should have thrown a ResourceException");
    } catch (final ResourceException e) {
      Assert.assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, e.getStatus());
    } finally {
      this.releaseClient(searchClientResource);
    }
  }
  /**
   * Handles POST requests. It retrieves a list of mails and generate requests to target resources.
   *
   * @param entity The representation of the mails list.
   * @throws ResourceException
   */
  @Post
  public void acceptMails(Representation entity) throws ResourceException {

    // 1 - Get list of identifiers for the mails in the inbox
    final List<String> mailIdentifiers = getMailIdentifiers();

    // 2 - Process the list of mails
    final List<String> mailsSuccessful = new ArrayList<String>();
    final Map<String, String> mailsUnsuccessful = new HashMap<String, String>();
    Representation mail;
    for (final String mailIdentifier : mailIdentifiers) {
      try {
        mail = getMail(mailIdentifier);
        if (mail != null) {
          this.resolver = getResolver(mailIdentifier, mail);
          callTarget(this.resolver);
          deleteMail(mailIdentifier);
          mailsSuccessful.add(mailIdentifier);
        }
      } catch (ResourceException e) {
        mailsUnsuccessful.put(mailIdentifier, e.getMessage());
      }
    }

    // 3 - Set response for timer client
    getResponse().setEntity(getResponseRepresentation(mailsSuccessful, mailsUnsuccessful));
    getResponse().setStatus(getResponseStatus(mailsSuccessful, mailsUnsuccessful));
  }
  protected String buildUploadFailedHtmlResponse(Throwable t, Request request, Response response) {
    try {
      handleException(request, response, t);
    } catch (ResourceException e) {
      getLogger().debug("Got error while uploading artifact", t);

      StringBuffer resp = new StringBuffer();
      resp.append("<html>");
      resp.append("<body>");
      resp.append("<error>" + e.getMessage() + "</error>");
      resp.append("</body>");
      resp.append("</html>");

      String forceSuccess = request.getResourceRef().getQueryAsForm().getFirstValue("forceSuccess");

      if (!"true".equals(forceSuccess)) {
        response.setStatus(e.getStatus());
      }

      return resp.toString();
    }

    // We have an error at this point, can't get here
    return null;
  }
示例#6
0
  @Override
  public Representation represent(Variant variant) throws ResourceException {
    try {
      return super.represent(variant);
    } catch (ResourceException e) {
      // NEXUS-4238, NEXUS-4290
      // if it's server error based on HTTP Code, but NOT when Nexus throws a known 503
      // (see
      // org.sonatype.nexus.rest.AbstractResourceStoreContentPlexusResource.handleException(Request,
      // Response, Exception))
      final Status status = e.getStatus();
      if (status == null) {
        handleError(e);
      } else {
        final int code = status.getCode();
        if (Status.isServerError(code)
            && Status.SERVER_ERROR_SERVICE_UNAVAILABLE.getCode() != code) {
          handleError(e);
        }
      }

      throw e;
    } catch (RuntimeException e) {
      handleError(e);

      throw e;
    }
  }
 public void handlePut() {
   try {
     storeRepresentation(getRequest().getEntity());
   } catch (ResourceException e) {
     getResponse().setStatus(e.getStatus());
   }
 }
示例#8
0
 public void doGet(String path) {
   ClientResource cr = new ClientResource(testContext, BASE_URI + path);
   try {
     cr.get();
   } catch (ResourceException e) {
     e.printStackTrace();
     Assert.fail();
   }
 }
 // FIXME: Enable again (disabled due to ipad content negotiation trouble during mtd2011 demo)
 @Get("xml")
 public Representation serveXMLResult() {
   selectedMime = MimeHelper.XML;
   //		System.out.println("VersionedObjectResource.getRepresentation() returning XML");
   try {
     return getVersionAsXMLRepresentatioFromDatabase();
   } catch (ResourceException e) {
     getResponse().setStatus(e.getStatus());
     return new StringRepresentation(e.toString());
   }
 }
 /**
  * Create WADL documentation
  *
  * @param url application url
  * @param docPath repository name
  */
 protected void createWadl(String url, String docPath) {
   ClientResource cr = new ClientResource(url);
   DocWadl dw = new DocWadl(docPath);
   try {
     cr.options().write(dw.getWadlPrintStream());
     cr.options(MediaType.TEXT_HTML).write(dw.getHtmlPrintStream());
   } catch (ResourceException e) {
     e.printStackTrace();
   } catch (FileNotFoundException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
 }
示例#11
0
 public void doPut(String path, String fileToPut) {
   ClientResource cr = new ClientResource(testContext, BASE_URI + path);
   LocalReference ref = new LocalReference(fileToPut);
   ref.setProtocol(Protocol.CLAP);
   ClientResource local = new ClientResource(ref);
   Representation rep = local.get();
   if (fileToPut.endsWith(".csv")) rep.setMediaType(MediaType.TEXT_CSV);
   try {
     cr.put(rep);
   } catch (ResourceException e) {
     e.printStackTrace();
     Assert.fail();
   }
 }
示例#12
0
  @Override
  public void removeRepresentations() throws ResourceException {
    try {
      super.removeRepresentations();
    } catch (ResourceException e) {
      if (Status.isServerError(e.getStatus().getCode())) {
        handleError(e);
      }
      throw e;
    } catch (RuntimeException e) {
      handleError(e);

      throw e;
    }
  }
 public GetCountry getCountry() {
   GetCountry res = null;
   String post =
       "{\"method\":\"getCountry\",\"header\":{\"wsKey\":\"" + KEY + "\"},\"parameters\":[]}";
   ClientResource cr = new ClientResource(uri + getSignatures(post));
   try {
     res = gson.fromJson(cr.post(post).getText(), GetCountry.class);
   } catch (JsonSyntaxException e) {
     e.printStackTrace();
   } catch (ResourceException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
   return res;
 }
示例#14
0
  public void doDelete(String path) {
    ClientResource cr = new ClientResource(testContext, BASE_URI + path);
    try {
      cr.delete();
    } catch (ResourceException e) {
      e.printStackTrace();
      Assert.fail();
    }

    try {
      cr.get();
      Assert.fail("resource still exists after delete");
    } catch (ResourceException e) {

    }
  }
 public StartSession getStartSession() {
   StartSession res = null;
   String post =
       "{\"method\":\"startSession\",\"header\":{\"wsKey\":\"" + KEY + "\"},\"parameters\":[]}";
   String sig = getSignatures(post);
   ClientResource cr = new ClientResource(uri + sig);
   try {
     res = gson.fromJson(cr.post(post).getText(), StartSession.class);
   } catch (JsonSyntaxException e) {
     e.printStackTrace();
   } catch (ResourceException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
   return res;
 }
  @Override
  public void handle(Request request, Response response) {
    super.handle(request, response);

    try {
      if (request.getMethod().equals(Method.GET)) {

        try {
          if ("users".equalsIgnoreCase(request.getResourceRef().getLastSegment())) {
            UserListValue users = importer.users();
            StringRepresentation result =
                new StringRepresentation(
                    users.toJSON(),
                    MediaType.APPLICATION_JSON,
                    Language.DEFAULT,
                    CharacterSet.UTF_8);
            response.setStatus(Status.SUCCESS_OK);
            response.setEntity(result);
          } else if ("groups".equalsIgnoreCase(request.getResourceRef().getLastSegment())) {
            GroupListValue groups = importer.groups();
            StringRepresentation result =
                new StringRepresentation(
                    groups.toJSON(),
                    MediaType.APPLICATION_JSON,
                    Language.DEFAULT,
                    CharacterSet.UTF_8);
            response.setStatus(Status.SUCCESS_OK);
            response.setEntity(result);
          }
        } catch (ResourceException e) {
          response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
          response.setEntity(e.getStatus().getDescription(), MediaType.TEXT_PLAIN);
        }

      } else {
        response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
      }
    } finally {
      request.release();
    }
  }
 @Delete("json")
 public Representation batchDelete(final String jsonContent) {
   LOG.info("Batch delete witnesses " + jsonContent);
   JsonParser parser = new JsonParser();
   JsonArray jsonArray = parser.parse(jsonContent).getAsJsonArray();
   Set<Usage> usage = new HashSet<Usage>();
   for (Iterator<JsonElement> itr = jsonArray.iterator(); itr.hasNext(); ) {
     JsonElement ele = itr.next();
     Long id = ele.getAsLong();
     Witness w = this.witnessDao.find(id);
     if (w != null) {
       try {
         usage.addAll(this.remover.remove(w));
       } catch (ResourceException e) {
         LOG.warn(e.toString());
       }
     } else {
       LOG.warn("Witness ID " + id + " is not a valid witness for this workspace");
     }
   }
   Gson gson = new Gson();
   return toJsonRepresentation(gson.toJson(usage));
 }
  @Test
  public void testErrorSearchRdfWithInvalidArtifactID() throws Exception {
    // prepare:
    final ClientResource searchClientResource =
        new ClientResource(this.getUrl(PoddWebConstants.PATH_SEARCH));

    // there is no need to authenticate or have a test artifact as the
    // artifact ID is checked
    // for first
    try {
      searchClientResource.addQueryParameter(PoddWebConstants.KEY_SEARCHTERM, "Scan");
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_ARTIFACT_IDENTIFIER, "http://no.such.artifact");
      searchClientResource.addQueryParameter(
          PoddWebConstants.KEY_SEARCH_TYPES, "http://purl.org/podd/ns/poddScience#Platform");

      searchClientResource.get(MediaType.APPLICATION_RDF_XML);
      Assert.fail("Should have thrown a ResourceException");
    } catch (final ResourceException e) {
      Assert.assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, e.getStatus());
    } finally {
      this.releaseClient(searchClientResource);
    }
  }
  public GetSongSearchResults getSongSearchResults(
      String query, Integer limit, Integer offset, GetCountry country) {

    GetSongSearchResults res = null;
    ClientResource cr = null;
    String post =
        "{\"method\":\"getSongSearchResults\",\"header\":{\"wsKey\":\""
            + KEY
            + "\"},\"parameters\":{\"query\":\""
            + query
            + "\",\"country\":"
            + country.getResult()
            + ",\"limit\":\""
            + limit
            + "\",\"offset\":\""
            + offset
            + "\"}}";
    //		String post = "{\"method\":\"getSongSearchResults\",\"header\":{\"wsKey\":\""+ KEY
    //						+ "\"},\"parameters\":{\"query\":\""+query
    //						+"\",\"country\":\"\",\"limit\":\""+limit
    //						+"\",\"offset\":\""+offset+"\"}}";
    String sig = getSignatures(post);

    cr = new ClientResource(uri + sig);
    try {

      res = gson.fromJson(cr.post(post).getText(), GetSongSearchResults.class);
    } catch (JsonSyntaxException e) {
      e.printStackTrace();
    } catch (ResourceException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return res;
  }
示例#20
0
  /**
   * fire the supplied event to my listeners
   *
   * @param event
   */
  protected void fireEvent(EventType event) {
    Vector<URI> toDitch = null;

    for (Iterator<URI> url = _myURIs.values().iterator(); url.hasNext(); ) {
      URI thisURI = url.next();

      try {
        ClientResource client = new ClientResource(thisURI.toString());
        fireThisEvent(client, event);
      } catch (ResourceException re) {
        if (re.getStatus().getCode() == 1001) {
          if (toDitch == null) toDitch = new Vector<URI>();
          toDitch.add(thisURI);
        } else re.printStackTrace();
      }
    }

    // ok, are we ditching any?
    if (toDitch != null) {
      // yup, work through them
      for (Iterator<URI> iterator = toDitch.iterator(); iterator.hasNext(); ) {
        URI thisURI = (URI) iterator.next();

        Set<Integer> mine = _myURIs.keySet();
        for (Iterator<Integer> iterator2 = mine.iterator(); iterator2.hasNext(); ) {
          Integer thisId = (Integer) iterator2.next();
          if (_myURIs.get(thisId).equals(thisURI)) {
            _myURIs.remove(thisId);
          }
        }
      }

      // and close.
      toDitch.removeAllElements();
    }
  }
  /** Test getting a task variable. GET runtime/tasks/{taskId}/variables/{variableName}/data */
  public void testGetTaskVariableDataForIllegalVariables() throws Exception {
    try {
      // Test variable behaviour on standalone tasks
      Task task = taskService.newTask();
      taskService.saveTask(task);
      taskService.setVariableLocal(
          task.getId(), "localTaskVariable", "this is a plain string variable");

      // Try getting data for non-binary variable
      ClientResource client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE_DATA, task.getId(), "localTaskVariable"));
      try {
        client.get();
        fail("Exception expected");
      } catch (ResourceException expected) {
        assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
        assertEquals(
            "The variable does not have a binary data stream.",
            expected.getStatus().getDescription());
      }

      // Try getting data for unexisting property
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE_DATA, task.getId(), "unexistingVariable"));
      try {
        client.get();
        fail("Exception expected");
      } catch (ResourceException expected) {
        assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
        assertEquals(
            "Task '" + task.getId() + "' doesn't have a variable with name: 'unexistingVariable'.",
            expected.getStatus().getDescription());
      }

    } finally {
      // Clean adhoc-tasks even if test fails
      List<Task> tasks = taskService.createTaskQuery().list();
      for (Task task : tasks) {
        taskService.deleteTask(task.getId(), true);
      }
    }
  }
示例#22
0
  @Deployment(
      resources = {
        "org/activiti/rest/api/management/JobCollectionResourceTest.testTimerProcess.bpmn20.xml"
      })
  public void testGetJobs() throws Exception {
    Calendar hourAgo = Calendar.getInstance();
    hourAgo.add(Calendar.HOUR, -1);

    Calendar inAnHour = Calendar.getInstance();
    inAnHour.add(Calendar.HOUR, 1);

    // Start process, forcing error on job-execution
    ProcessInstance processInstance =
        runtimeService.startProcessInstanceByKey(
            "timerProcess", Collections.singletonMap("error", (Object) Boolean.TRUE));

    Job timerJob =
        managementService
            .createJobQuery()
            .processInstanceId(processInstance.getId())
            .timers()
            .singleResult();
    assertNotNull(timerJob);

    for (int i = 0; i < timerJob.getRetries(); i++) {
      // Force execution of job until retries are exhausted
      try {
        managementService.executeJob(timerJob.getId());
        fail();
      } catch (ActivitiException expected) {
        // Ignore, we expect the exception
      }
    }
    timerJob =
        managementService
            .createJobQuery()
            .processInstanceId(processInstance.getId())
            .timers()
            .singleResult();
    assertEquals(0, timerJob.getRetries());

    // Fetch the async-job (which has retries left)
    Job asyncJob =
        managementService
            .createJobQuery()
            .processInstanceId(processInstance.getId())
            .withRetriesLeft()
            .singleResult();

    // Test fetching all jobs
    String url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION);
    assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId());

    // Fetch using job-id
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?id=" + asyncJob.getId();
    assertResultsPresentInDataResponse(url, asyncJob.getId());

    // Fetch using processInstanceId
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?processInstanceId="
            + processInstance.getId();
    assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId());

    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?processInstanceId=unexisting";
    assertResultsPresentInDataResponse(url);

    // Fetch using executionId
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?executionId="
            + asyncJob.getExecutionId();
    assertResultsPresentInDataResponse(url, asyncJob.getId());

    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?executionId="
            + timerJob.getExecutionId();
    assertResultsPresentInDataResponse(url, timerJob.getId());

    // Fetch using processDefinitionId
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?processDefinitionId="
            + processInstance.getProcessDefinitionId();
    assertResultsPresentInDataResponse(url, asyncJob.getId(), timerJob.getId());

    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?processDefinitionId=unexisting";
    assertResultsPresentInDataResponse(url);

    // Fetch using withRetriesLeft
    url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?withRetriesLeft=true";
    assertResultsPresentInDataResponse(url, asyncJob.getId());

    // Fetch using executable
    url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?executable=true";
    assertResultsPresentInDataResponse(url, asyncJob.getId());

    // Fetch using timers only
    url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?timersOnly=true";
    assertResultsPresentInDataResponse(url, timerJob.getId());

    // Combining messagesOnly with timersOnly should result in exception
    ClientResource client =
        getAuthenticatedClient(
            RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
                + "?timersOnly=true&messagesOnly=true");
    try {
      client.get();
      fail("Exception expected");
    } catch (ResourceException expected) {
      assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus());
      assertEquals(
          "Only one of 'timersOnly' or 'messagesOnly' can be provided.",
          expected.getStatus().getDescription());
    }

    // Fetch using dueBefore
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?dueBefore="
            + getISODateString(inAnHour.getTime());
    assertResultsPresentInDataResponse(url, timerJob.getId());

    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?dueBefore="
            + getISODateString(hourAgo.getTime());
    assertResultsPresentInDataResponse(url);

    // Fetch using dueAfter
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?dueAfter="
            + getISODateString(hourAgo.getTime());
    assertResultsPresentInDataResponse(url, timerJob.getId());

    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?dueAfter="
            + getISODateString(inAnHour.getTime());
    assertResultsPresentInDataResponse(url);

    // Fetch using withException
    url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?withException=true";
    assertResultsPresentInDataResponse(url, timerJob.getId());

    // Fetch with exceptionMessage
    url =
        RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION)
            + "?exceptionMessage="
            + timerJob.getExceptionMessage();
    assertResultsPresentInDataResponse(url, timerJob.getId());

    // Fetch with empty exceptionMessage
    url = RestUrls.createRelativeResourceUrl(RestUrls.URL_JOB_COLLECTION) + "?exceptionMessage=";
    assertResultsPresentInDataResponse(url);
  }
示例#23
0
 public AATokenValidationException(String ref, ResourceException x) {
   super(x.getStatus(), ref, x);
 }
  /** Test getting a task variable. GET runtime/tasks/{taskId}/variables/{variableName} */
  @Deployment
  public void testGetTaskVariable() throws Exception {
    try {
      // Test variable behaviour on standalone tasks
      Task task = taskService.newTask();
      taskService.saveTask(task);
      taskService.setVariableLocal(task.getId(), "localTaskVariable", "localValue");

      ClientResource client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE, task.getId(), "localTaskVariable"));
      Representation response = client.get();
      assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

      JsonNode responseNode = objectMapper.readTree(response.getStream());
      assertNotNull(responseNode);
      assertEquals("local", responseNode.get("scope").asText());
      assertEquals("localValue", responseNode.get("value").asText());
      assertEquals("localTaskVariable", responseNode.get("name").asText());
      assertEquals("string", responseNode.get("type").asText());

      // Test variable behaviour for a process-task
      ProcessInstance processInstance =
          runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              Collections.singletonMap("sharedVariable", (Object) "processValue"));
      Task processTask =
          taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();

      taskService.setVariableLocal(processTask.getId(), "sharedVariable", "taskValue");

      // ANY scope, local should get precedence
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE, processTask.getId(), "sharedVariable"));
      response = client.get();
      assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

      responseNode = objectMapper.readTree(response.getStream());
      assertNotNull(responseNode);
      assertEquals("local", responseNode.get("scope").asText());
      assertEquals("taskValue", responseNode.get("value").asText());
      assertEquals("sharedVariable", responseNode.get("name").asText());
      assertEquals("string", responseNode.get("type").asText());

      // LOCAL scope
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                      RestUrls.URL_TASK_VARIABLE, processTask.getId(), "sharedVariable")
                  + "?scope=local");
      response = client.get();
      assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

      responseNode = objectMapper.readTree(response.getStream());
      assertNotNull(responseNode);
      assertEquals("local", responseNode.get("scope").asText());
      assertEquals("taskValue", responseNode.get("value").asText());
      assertEquals("sharedVariable", responseNode.get("name").asText());
      assertEquals("string", responseNode.get("type").asText());

      // GLOBAL scope
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                      RestUrls.URL_TASK_VARIABLE, processTask.getId(), "sharedVariable")
                  + "?scope=global");
      response = client.get();
      assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

      responseNode = objectMapper.readTree(response.getStream());
      assertNotNull(responseNode);
      assertEquals("global", responseNode.get("scope").asText());
      assertEquals("processValue", responseNode.get("value").asText());
      assertEquals("sharedVariable", responseNode.get("name").asText());
      assertEquals("string", responseNode.get("type").asText());

      // Illegal scope
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                      RestUrls.URL_TASK_VARIABLE, processTask.getId(), "sharedVariable")
                  + "?scope=illegal");
      try {
        response = client.get();
        fail("Exception expected");
      } catch (ResourceException expected) {
        assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus());
        assertEquals("Invalid variable scope: 'illegal'", expected.getStatus().getDescription());
      }

      // Unexisting task
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE, "unexisting", "sharedVariable"));
      try {
        response = client.get();
        fail("Exception expected");
      } catch (ResourceException expected) {
        assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
        assertEquals("task unexisting doesn't exist", expected.getStatus().getDescription());
      }

      // Unexisting variable
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE, processTask.getId(), "unexistingVariable"));
      try {
        response = client.get();
        fail("Exception expected");
      } catch (ResourceException expected) {
        assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
        assertEquals(
            "Task '"
                + processTask.getId()
                + "' doesn't have a variable with name: 'unexistingVariable'.",
            expected.getStatus().getDescription());
      }

    } finally {
      // Clean adhoc-tasks even if test fails
      List<Task> tasks = taskService.createTaskQuery().list();
      for (Task task : tasks) {
        if (task.getExecutionId() == null) {
          taskService.deleteTask(task.getId(), true);
        }
      }
    }
  }
  /**
   * Test updating a single task variable in all scopes, including "not found" check.
   *
   * <p>PUT runtime/tasks/{taskId}/variables/{variableName}
   */
  @Deployment
  public void testUpdateTaskVariable() throws Exception {
    ProcessInstance processInstance =
        runtimeService.startProcessInstanceByKey(
            "oneTaskProcess",
            Collections.singletonMap("overlappingVariable", (Object) "processValue"));
    Task task =
        taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
    taskService.setVariableLocal(task.getId(), "overlappingVariable", "taskValue");

    // Update variable without scope, local should be presumed -> local updated and global should be
    // retained
    ObjectNode requestNode = objectMapper.createObjectNode();
    requestNode.put("name", "overlappingVariable");
    requestNode.put("value", "updatedLocalValue");
    requestNode.put("type", "string");

    ClientResource client =
        getAuthenticatedClient(
            RestUrls.createRelativeResourceUrl(
                RestUrls.URL_TASK_VARIABLE, task.getId(), "overlappingVariable"));
    Representation response = client.put(requestNode);
    assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

    JsonNode responseNode = objectMapper.readTree(response.getStream());
    assertNotNull(responseNode);
    assertEquals("updatedLocalValue", responseNode.get("value").asText());
    assertEquals("local", responseNode.get("scope").asText());
    // Check local value is changed in engine and global one remains unchanged
    assertEquals(
        "updatedLocalValue", taskService.getVariableLocal(task.getId(), "overlappingVariable"));
    assertEquals(
        "processValue", runtimeService.getVariable(task.getExecutionId(), "overlappingVariable"));

    // Update variable in local scope
    response.release();
    requestNode = objectMapper.createObjectNode();
    requestNode.put("name", "overlappingVariable");
    requestNode.put("value", "updatedLocalValueOnceAgain");
    requestNode.put("type", "string");
    requestNode.put("scope", "local");
    response = client.put(requestNode);
    assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

    responseNode = objectMapper.readTree(response.getStream());
    assertNotNull(responseNode);
    assertEquals("updatedLocalValueOnceAgain", responseNode.get("value").asText());
    assertEquals("local", responseNode.get("scope").asText());
    // Check local value is changed in engine and global one remains unchanged
    assertEquals(
        "updatedLocalValueOnceAgain",
        taskService.getVariableLocal(task.getId(), "overlappingVariable"));
    assertEquals(
        "processValue", runtimeService.getVariable(task.getExecutionId(), "overlappingVariable"));

    // Update variable in global scope
    response.release();
    requestNode = objectMapper.createObjectNode();
    requestNode.put("name", "overlappingVariable");
    requestNode.put("value", "updatedInGlobalScope");
    requestNode.put("type", "string");
    requestNode.put("scope", "global");
    response = client.put(requestNode);
    assertEquals(Status.SUCCESS_OK, client.getResponse().getStatus());

    responseNode = objectMapper.readTree(response.getStream());
    assertNotNull(responseNode);
    assertEquals("updatedInGlobalScope", responseNode.get("value").asText());
    assertEquals("global", responseNode.get("scope").asText());
    // Check global value is changed in engine and local one remains unchanged
    assertEquals(
        "updatedLocalValueOnceAgain",
        taskService.getVariableLocal(task.getId(), "overlappingVariable"));
    assertEquals(
        "updatedInGlobalScope",
        runtimeService.getVariable(task.getExecutionId(), "overlappingVariable"));

    // Try updating with mismatch between URL and body variableName unexisting property
    try {
      requestNode.put("name", "unexistingVariable");
      client.put(requestNode);
      fail("Exception expected");
    } catch (ResourceException expected) {
      assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus());
      assertEquals(
          "Variable name in the body should be equal to the name used in the requested URL.",
          expected.getStatus().getDescription());
    }

    // Try updating unexisting property
    try {
      client =
          getAuthenticatedClient(
              RestUrls.createRelativeResourceUrl(
                  RestUrls.URL_TASK_VARIABLE, task.getId(), "unexistingVariable"));
      requestNode.put("name", "unexistingVariable");
      client.put(requestNode);
      fail("Exception expected");
    } catch (ResourceException expected) {
      assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
      assertEquals(
          "Task '" + task.getId() + "' doesn't have a variable with name: 'unexistingVariable'.",
          expected.getStatus().getDescription());
    }
  }
  /**
   * Test deleting a single task variable in all scopes, including "not found" check.
   *
   * <p>DELETE runtime/tasks/{taskId}/variables/{variableName}
   */
  @Deployment
  public void testDeleteTaskVariable() throws Exception {
    ProcessInstance processInstance =
        runtimeService.startProcessInstanceByKey(
            "oneTaskProcess",
            Collections.singletonMap("overlappingVariable", (Object) "processValue"));
    Task task =
        taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
    taskService.setVariableLocal(task.getId(), "overlappingVariable", "taskValue");
    taskService.setVariableLocal(task.getId(), "anotherTaskVariable", "taskValue");

    // Delete variable without scope, local should be presumed -> local removed and global should be
    // retained
    ClientResource client =
        getAuthenticatedClient(
            RestUrls.createRelativeResourceUrl(
                RestUrls.URL_TASK_VARIABLE, task.getId(), "overlappingVariable"));
    Representation response = client.delete();
    assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
    assertEquals(0L, response.getSize());
    assertFalse(taskService.hasVariableLocal(task.getId(), "overlappingVariable"));
    assertTrue(taskService.hasVariable(task.getId(), "overlappingVariable"));

    // Delete local scope variable
    client.release();
    client =
        getAuthenticatedClient(
            RestUrls.createRelativeResourceUrl(
                    RestUrls.URL_TASK_VARIABLE, task.getId(), "anotherTaskVariable")
                + "?scope=local");
    response = client.delete();
    assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
    assertEquals(0L, response.getSize());
    assertFalse(taskService.hasVariableLocal(task.getId(), "anotherTaskVariable"));

    // Delete global scope variable
    assertTrue(taskService.hasVariable(task.getId(), "overlappingVariable"));
    client.release();
    client =
        getAuthenticatedClient(
            RestUrls.createRelativeResourceUrl(
                    RestUrls.URL_TASK_VARIABLE, task.getId(), "overlappingVariable")
                + "?scope=global");
    response = client.delete();
    assertEquals(Status.SUCCESS_NO_CONTENT, client.getResponse().getStatus());
    assertEquals(0L, response.getSize());
    assertFalse(taskService.hasVariable(task.getId(), "overlappingVariable"));

    // Run the same delete again, variable is not there so 404 should be returned
    client.release();
    try {
      client.delete();
      fail("Exception expected");
    } catch (ResourceException expected) {
      assertEquals(Status.CLIENT_ERROR_NOT_FOUND, expected.getStatus());
      assertEquals(
          "Task '"
              + task.getId()
              + "' doesn't have a variable 'overlappingVariable' in scope global",
          expected.getStatus().getDescription());
    }
  }