1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.linecorp.centraldogma.server.internal.api.converter;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20
21 import java.lang.reflect.ParameterizedType;
22 import java.util.List;
23
24 import javax.annotation.Nullable;
25
26 import com.fasterxml.jackson.databind.JsonNode;
27 import com.fasterxml.jackson.databind.node.ArrayNode;
28 import com.fasterxml.jackson.databind.node.JsonNodeType;
29 import com.google.common.collect.ImmutableList;
30
31 import com.linecorp.armeria.common.AggregatedHttpRequest;
32 import com.linecorp.armeria.server.ServiceRequestContext;
33 import com.linecorp.armeria.server.annotation.JacksonRequestConverterFunction;
34 import com.linecorp.armeria.server.annotation.RequestConverterFunction;
35 import com.linecorp.centraldogma.common.Change;
36 import com.linecorp.centraldogma.common.ChangeType;
37
38
39
40
41 public final class ChangesRequestConverter implements RequestConverterFunction {
42
43 private final JacksonRequestConverterFunction delegate = new JacksonRequestConverterFunction();
44
45 @Override
46 public List<Change<?>> convertRequest(
47 ServiceRequestContext ctx, AggregatedHttpRequest request, Class<?> expectedResultType,
48 @Nullable ParameterizedType expectedParameterizedResultType) throws Exception {
49
50 final JsonNode node = (JsonNode) delegate.convertRequest(ctx, request, JsonNode.class, null);
51 if (node == null) {
52 return RequestConverterFunction.fallthrough();
53 }
54
55 final ArrayNode changesNode;
56 if (node.getNodeType() == JsonNodeType.ARRAY) {
57 changesNode = (ArrayNode) node;
58 } else {
59 final JsonNode maybeChangesNode = node.get("changes");
60 if (maybeChangesNode != null) {
61 if (maybeChangesNode.getNodeType() == JsonNodeType.ARRAY) {
62 changesNode = (ArrayNode) maybeChangesNode;
63 } else {
64 throw new IllegalArgumentException("'changes' must be an array.");
65 }
66 } else {
67
68 return ImmutableList.of(readChange(node));
69 }
70 }
71
72 final ImmutableList.Builder<Change<?>> builder = ImmutableList.builder();
73 for (JsonNode change : changesNode) {
74 builder.add(readChange(change));
75 }
76 return builder.build();
77 }
78
79 private static Change<?> readChange(JsonNode node) {
80 checkArgument(node.get("path") != null && node.get("type") != null,
81 "a change should have a path and a type");
82 final ChangeType changeType = ChangeType.parse(node.get("type").textValue());
83 if (changeType != ChangeType.REMOVE) {
84 checkArgument(node.get("content") != null, "a change should have a content.");
85 }
86
87 final String path = node.get("path").textValue();
88 if (changeType == ChangeType.UPSERT_TEXT) {
89 return Change.ofTextUpsert(path, node.get("content").textValue());
90 }
91 if (changeType == ChangeType.UPSERT_JSON) {
92 return Change.ofJsonUpsert(path, node.get("content"));
93 }
94 if (changeType == ChangeType.REMOVE) {
95 return Change.ofRemoval(path);
96 }
97 if (changeType == ChangeType.RENAME) {
98 return Change.ofRename(path, node.get("content").textValue());
99 }
100 if (changeType == ChangeType.APPLY_TEXT_PATCH) {
101 return Change.ofTextPatch(path, node.get("content").textValue());
102 }
103 if (changeType == ChangeType.APPLY_JSON_PATCH) {
104 return Change.ofJsonPatch(path, node.get("content"));
105 }
106
107
108 throw new Error();
109 }
110 }