@ApiOperation(value = "Update a model", tags = { "Models" }, notes = "All request values are optional. "
            + "For example, you can only include the name attribute in the request body JSON-object, only updating the name of the model, leaving all other fields unaffected. "
            + "When an attribute is explicitly included and is set to null, the model-value will be updated to null. ")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Indicates the model was found and updated."),
            @ApiResponse(code = 404, message = "Indicates the requested model was not found.")
    })
    @PutMapping(value = "/repository/models/{modelId}", produces = "application/json")
    public ModelResponse updateModel(@ApiParam(name = "modelId") @PathVariable String modelId, @RequestBody ModelRequest modelRequest) {
        Model model = getModelFromRequest(modelId);

        if (modelRequest.isCategoryChanged()) {
            model.setCategory(modelRequest.getCategory());
        }
        if (modelRequest.isDeploymentChanged()) {
            model.setDeploymentId(modelRequest.getDeploymentId());
        }
        if (modelRequest.isKeyChanged()) {
            model.setKey(modelRequest.getKey());
        }
        if (modelRequest.isMetaInfoChanged()) {
            model.setMetaInfo(modelRequest.getMetaInfo());
        }
        if (modelRequest.isNameChanged()) {
            model.setName(modelRequest.getName());
        }
        if (modelRequest.isVersionChanged()) {
            model.setVersion(modelRequest.getVersion());
        }
        if (modelRequest.isTenantIdChanged()) {
            model.setTenantId(modelRequest.getTenantId());
        }

        repositoryService.saveModel(model);
        return restResponseFactory.createModelResponse(model);
    }
@Test
    @Deployment(resources = { "org/flowable/rest/service/api/repository/oneTaskProcess.bpmn20.xml" })
    public void testUpdateModel() throws Exception {

        Model model = null;
        try {
            Calendar createTime = Calendar.getInstance();
            createTime.set(Calendar.MILLISECOND, 0);
            processEngineConfiguration.getClock().setCurrentTime(createTime.getTime());

            model = repositoryService.newModel();
            model.setCategory("Model category");
            model.setKey("Model key");
            model.setMetaInfo("Model metainfo");
            model.setName("Model name");
            model.setVersion(2);
            repositoryService.saveModel(model);

            Calendar updateTime = Calendar.getInstance();
            updateTime.set(Calendar.MILLISECOND, 0);
            updateTime.add(Calendar.HOUR, 1);
            processEngineConfiguration.getClock().setCurrentTime(updateTime.getTime());

            // Create update request
            ObjectNode requestNode = objectMapper.createObjectNode();
            requestNode.put("name", "Updated name");
            requestNode.put("category", "Updated category");
            requestNode.put("key", "Updated key");
            requestNode.put("metaInfo", "Updated metainfo");
            requestNode.put("deploymentId", deploymentId);
            requestNode.put("version", 3);
            requestNode.put("tenantId", "myTenant");

            HttpPut httpPut = new HttpPut(SERVER_URL_PREFIX + RestUrls.createRelativeResourceUrl(RestUrls.URL_MODEL, model.getId()));
            httpPut.setEntity(new StringEntity(requestNode.toString()));
            CloseableHttpResponse response = executeRequest(httpPut, HttpStatus.SC_OK);

            JsonNode responseNode = objectMapper.readTree(response.getEntity().getContent());
            closeResponse(response);
            assertThat(responseNode).isNotNull();
            assertThatJson(responseNode)
                    .when(Option.IGNORING_EXTRA_FIELDS)
                    .isEqualTo("{"
                            + "name: 'Updated name',"
                            + "key: 'Updated key',"
                            + "category: 'Updated category',"
                            + "version: 3,"
                            + "metaInfo: 'Updated metainfo',"
                            + "deploymentId: '" + deploymentId + "',"
                            + "id: '" + model.getId() + "',"
                            + "tenantId: 'myTenant',"
                            + "url: '" + SERVER_URL_PREFIX + RestUrls.createRelativeResourceUrl(RestUrls.URL_MODEL, model.getId()) + "',"
                            + "deploymentUrl: '" + SERVER_URL_PREFIX + RestUrls.createRelativeResourceUrl(RestUrls.URL_DEPLOYMENT, deploymentId) + "',"
                            + "createTime: " + new TextNode(getISODateStringWithTZ(createTime.getTime())) + ","
                            + "lastUpdateTime: " + new TextNode(getISODateStringWithTZ(updateTime.getTime()))
                            + "}");

        } finally {
            try {
                repositoryService.deleteModel(model.getId());
            } catch (Throwable ignore) {
                // Ignore, model might not be created
            }
        }
    }