@Nonnull @Override public JsonNode migrate(@Nonnull final JsonNode input) throws SwaggerMigrationException { Objects.requireNonNull(input); try { return patch.apply(input); } catch (JsonPatchException e) { throw new SwaggerMigrationException(e); } } };
@Override public JsonPatchEdit deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode edit = oc.readTree(jp); final Builder eb = JsonPatchEdit.withChecksum(edit.get("checksum").asText()); eb.clientVersion(edit.get("clientVersion").asLong()); eb.serverVersion(edit.get("serverVersion").asLong()); eb.checksum(edit.get("checksum").asText()); final JsonNode diffsNode = edit.get("diffs"); if (!diffsNode.isNull()) { eb.patch(JsonPatch.fromJson(diffsNode)); } return eb.build(); } }
JsonPatch getPatch() { final List<JsonPatchOperation> list = Lists.newArrayList(); for (final DiffOperation op: diffs) list.add(op.asJsonPatchOperation()); return new JsonPatch(list); }
@Override public void serializeWithType(final JsonGenerator jgen, final SerializerProvider provider, final TypeSerializer typeSer) throws IOException { serialize(jgen, provider); } }
private JsonNode postMigrate(final JsonNode input) throws SwaggerMigrationException { final JsonNode typeNode = input.path("type"); if (!typeNode.isTextual()) { return input; } if (!"File".equals(typeNode.textValue())) { return input; } try { return fileTypePatch.apply(input); } catch (JsonPatchException e) { throw new SwaggerMigrationException(e); } }
@Test public void whenOneOperationFailsNextOperationIsNotCalled() throws JsonPatchException { final String message = "foo"; when(op1.apply(any(JsonNode.class))) .thenThrow(new JsonPatchException(message)); final JsonPatch patch = new JsonPatch(ImmutableList.of(op1, op2)); try { patch.apply(FACTORY.nullNode()); fail("No exception thrown!!"); } catch (JsonPatchException e) { assertEquals(e.getMessage(), message); } verifyZeroInteractions(op2); } }
@Override public JsonPatchMessage deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode node = oc.readTree(jp); final String documentId = node.get("id").asText(); final String clientId = node.get("clientId").asText(); final JsonNode jsonEdits = node.get("edits"); final Queue<JsonPatchEdit> edits = new ConcurrentLinkedQueue<JsonPatchEdit>(); if (jsonEdits.isArray()) { for (JsonNode edit : jsonEdits) { if (edit.isNull()) { continue; } final Builder eb = JsonPatchEdit.withChecksum(edit.get("checksum").asText()); eb.clientVersion(edit.get("clientVersion").asLong()); eb.serverVersion(edit.get("serverVersion").asLong()); final JsonNode diffsNode = edit.get("diffs"); if (!diffsNode.isNull()) { eb.patch(JsonPatch.fromJson(diffsNode)); } edits.add(eb.build()); } } return new JsonPatchMessage(documentId, clientId, edits); } }
ObjectMapper mapper = new ObjectMapper(); JsonNode targetJson = mapper.readValue(tmpOutputStream.toByteArray(), JsonNode.class); JsonPatch patch = JsonPatch.fromJson(mapper.readValue(request.getInputStream(), JsonNode.class)); JsonNode result = patch.apply(targetJson); ByteArrayOutputStream targetOutputStream = new ByteArrayOutputStream(); mapper.writeValue(targetOutputStream, result);
private static JsonNode patch(final JsonPatchEdit edit, final JsonNode target) { try { return edit.diff().jsonPatch().apply(target); } catch (final JsonPatchException e) { throw new RuntimeException(e.getMessage(), e); } }
@Test public void operationsAreCalledInOrder() throws JsonPatchException { final JsonNode node1 = FACTORY.textNode("hello"); final JsonNode node2 = FACTORY.textNode("world"); when(op1.apply(node1)).thenReturn(node2); final JsonPatch patch = new JsonPatch(ImmutableList.of(op1, op2)); final ArgumentCaptor<JsonNode> captor = ArgumentCaptor.forClass(JsonNode.class); patch.apply(node1); verify(op1, only()).apply(same(node1)); verify(op2, only()).apply(captor.capture()); assertSame(captor.getValue(), node2); }
@Test public void nullInputsDuringBuildAreRejected() throws IOException { try { JsonPatch.fromJson(null); fail("No exception thrown!!"); } catch (NullPointerException e) { assertEquals(e.getMessage(), BUNDLE.getMessage( "jsonPatch.nullInput")); } }
/** * Applies a JsonPatch to an object */ @SuppressWarnings("unchecked") public static <T> T applyPatch(T originalObj, String patchString) throws JsonProcessingException, IOException, JsonPatchException { // Parse the patch to JsonNode JsonNode patchNode = objectMapper.readTree(patchString); // Create the patch JsonPatch patch = JsonPatch.fromJson(patchNode); // Convert the original object to JsonNode JsonNode originalObjNode = objectMapper.valueToTree(originalObj); // Apply the patch TreeNode patchedObjNode = patch.apply(originalObjNode); // Convert the patched node to an updated obj return objectMapper.treeToValue(patchedObjNode, (Class<T>) originalObj.getClass()); }
/** * {@inheritDoc} */ @Override public void patchCluster(@NotBlank final String id, @NotNull final JsonPatch patch) throws GenieException { final ClusterEntity clusterEntity = this.findCluster(id); try { final Cluster clusterToPatch = JpaServiceUtils.toClusterDto(clusterEntity); log.debug("Will patch cluster {}. Original state: {}", id, clusterToPatch); final JsonNode clusterNode = MAPPER.readTree(clusterToPatch.toString()); final JsonNode postPatchNode = patch.apply(clusterNode); final Cluster patchedCluster = MAPPER.treeToValue(postPatchNode, Cluster.class); log.debug("Finished patching cluster {}. New state: {}", id, patchedCluster); this.updateEntityWithDtoContents(clusterEntity, patchedCluster); } catch (final JsonPatchException | IOException e) { log.error("Unable to patch cluster {} with patch {} due to exception.", id, patch, e); throw new GenieServerException(e.getLocalizedMessage(), e); } }
@DataProvider public Iterator<Object[]> getTests() throws IOException { final List<Object[]> list = Lists.newArrayList(); boolean valid; JsonPatch patch; JsonNode source, expected; for (final JsonNode element: testNode) { if (!element.has("patch")) continue; patch = JsonPatch.fromJson(element.get("patch")); source = element.get("doc"); expected = element.get("expected"); if (expected == null) expected = source; valid = !element.has("error"); list.add(new Object[]{source, patch, expected, valid}); } return list.iterator(); }
@Override public JsonNode transform(JsonNode patched) throws IOException { Iterator<Map.Entry<String, JsonNode>> nodeIterator = patched.get("message").fields(); while (nodeIterator.hasNext()) { Map.Entry<String, JsonNode> entry = nodeIterator.next(); if (!KNOWN_KEYS.contains(entry.getKey())) { String json = format(MOVE_OP, entry.getKey()); try { patched = JsonPatch.fromJson(JacksonUtils.getReader().readTree(json)).apply(patched); } catch (JsonPatchException e) { throw new RuntimeException("move operation could not be applied", e); } } } return patched; } }
/** * {@inheritDoc} */ @Override public void patchCommand(@NotBlank final String id, @NotNull final JsonPatch patch) throws GenieException { final CommandEntity commandEntity = this.findCommand(id); try { final Command commandToPatch = JpaServiceUtils.toCommandDto(commandEntity); log.debug("Will patch command {}. Original state: {}", id, commandToPatch); final JsonNode commandNode = MAPPER.readTree(commandToPatch.toString()); final JsonNode postPatchNode = patch.apply(commandNode); final Command patchedCommand = MAPPER.treeToValue(postPatchNode, Command.class); log.debug("Finished patching command {}. New state: {}", id, patchedCommand); this.updateEntityWithDtoContents(commandEntity, patchedCommand); } catch (final JsonPatchException | IOException e) { log.error("Unable to patch cluster {} with patch {} due to exception.", id, patch, e); throw new GenieServerException(e.getLocalizedMessage(), e); } }
ObjectMapper mapper = new ObjectMapper(); JsonNode targetJson = mapper.readValue(tmpOutputStream.toByteArray(), JsonNode.class); JsonPatch patch = JsonPatch.fromJson(mapper.readValue(request.getInputStream(), JsonNode.class)); JsonNode result = patch.apply(targetJson); ByteArrayOutputStream targetOutputStream = new ByteArrayOutputStream(); mapper.writeValue(targetOutputStream, result);