From: Straubs, Ralph (rs8887) Date: Tue, 22 Oct 2019 15:43:09 +0000 (-0500) Subject: Changes in preparation for the m2 model X-Git-Tag: 2.2.0~42^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=ffc78b2ad00d35e49e8ca3f8524483f6df171d50;p=policy%2Fmodels.git Changes in preparation for the m2 model 1) Replace enum 'ControlLoopTargetType' with 'String' -- symbols such as 'ControlLoopTargetType.VM' still work, but now expand into a String. This gives the ability to add new application-specific types. 2) Move 'ControlLoopEvent.payload' to 'VirtualControlLoopEvent'. This symbol isn't common to all 'ControlLoopEvent' types, and this definition collides with a 'payload' defined in our application. 3) Add 'RestManager.patch(...)', which performs a REST patch. 4) Add lombok getters and setters 5) Remove trailing spaces 6) Fix order of arguments in 'assertEquals' in 'ControlLoopTargetTypeTest' 7) Update Junit tests in 'RestTest' to include 'RestManager.patch(...)' Issue-ID: POLICY-1948 Signed-off-by: Straubs, Ralph (rs8887) Change-Id: I08e04ea3cbcf368c760b630bcfe23a4370cf94dc --- diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java index 43cd640c0..534e843f2 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopEvent.java @@ -24,47 +24,48 @@ package org.onap.policy.controlloop; import com.google.gson.annotations.SerializedName; import java.io.Serializable; import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter public abstract class ControlLoopEvent implements Serializable { private static final long serialVersionUID = 2391252138583119195L; - + @SerializedName("closedLoopControlName") private String closedLoopControlName; - + @SerializedName("version") private String version = "1.0.2"; - + @SerializedName("requestID") private UUID requestId; - + @SerializedName("closedLoopEventClient") private String closedLoopEventClient; - + @SerializedName("target_type") - private ControlLoopTargetType targetType; - + private String targetType; + @SerializedName("target") private String target; - + @SerializedName("from") private String from; - + @SerializedName("policyScope") private String policyScope; - + @SerializedName("policyName") private String policyName; - + @SerializedName("policyVersion") private String policyVersion; - + @SerializedName("closedLoopEventStatus") private ControlLoopEventStatus closedLoopEventStatus; - @SerializedName("payload") - private String payload; - public ControlLoopEvent() { } @@ -88,106 +89,9 @@ public abstract class ControlLoopEvent implements Serializable { this.policyName = event.policyName; this.policyVersion = event.policyVersion; this.closedLoopEventStatus = event.closedLoopEventStatus; - this.payload = event.payload; } public boolean isEventStatusValid() { return this.closedLoopEventStatus != null; } - - public String getClosedLoopControlName() { - return closedLoopControlName; - } - - public void setClosedLoopControlName(String closedLoopControlName) { - this.closedLoopControlName = closedLoopControlName; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public UUID getRequestId() { - return requestId; - } - - public void setRequestId(UUID requestId) { - this.requestId = requestId; - } - - public String getClosedLoopEventClient() { - return closedLoopEventClient; - } - - public void setClosedLoopEventClient(String closedLoopEventClient) { - this.closedLoopEventClient = closedLoopEventClient; - } - - public ControlLoopTargetType getTargetType() { - return targetType; - } - - public void setTargetType(ControlLoopTargetType targetType) { - this.targetType = targetType; - } - - public String getTarget() { - return target; - } - - public void setTarget(String target) { - this.target = target; - } - - public String getFrom() { - return from; - } - - public void setFrom(String from) { - this.from = from; - } - - public String getPolicyScope() { - return policyScope; - } - - public void setPolicyScope(String policyScope) { - this.policyScope = policyScope; - } - - public String getPolicyName() { - return policyName; - } - - public void setPolicyName(String policyName) { - this.policyName = policyName; - } - - public String getPolicyVersion() { - return policyVersion; - } - - public void setPolicyVersion(String policyVersion) { - this.policyVersion = policyVersion; - } - - public ControlLoopEventStatus getClosedLoopEventStatus() { - return closedLoopEventStatus; - } - - public void setClosedLoopEventStatus(ControlLoopEventStatus closedLoopEventStatus) { - this.closedLoopEventStatus = closedLoopEventStatus; - } - - public String getPayload() { - return payload; - } - - public void setPayload(String payload) { - this.payload = payload; - } } diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java index dd1854a1c..924291709 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopNotification.java @@ -27,7 +27,11 @@ import java.time.ZonedDateTime; import java.util.LinkedList; import java.util.List; import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter public abstract class ControlLoopNotification implements Serializable { private static final long serialVersionUID = 7538596984567127915L; @@ -36,7 +40,7 @@ public abstract class ControlLoopNotification implements Serializable { private String version = "1.0.2"; private UUID requestId; private String closedLoopEventClient; - private ControlLoopTargetType targetType; + private String targetType; private String target; private String from; private String policyScope; @@ -68,124 +72,4 @@ public abstract class ControlLoopNotification implements Serializable { this.setTargetType(event.getTargetType()); this.setTarget(event.getTarget()); } - - public String getClosedLoopControlName() { - return closedLoopControlName; - } - - public void setClosedLoopControlName(String closedLoopControlName) { - this.closedLoopControlName = closedLoopControlName; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public UUID getRequestId() { - return requestId; - } - - public void setRequestId(UUID requestId) { - this.requestId = requestId; - } - - public String getClosedLoopEventClient() { - return closedLoopEventClient; - } - - public void setClosedLoopEventClient(String closedLoopEventClient) { - this.closedLoopEventClient = closedLoopEventClient; - } - - public ControlLoopTargetType getTargetType() { - return targetType; - } - - public void setTargetType(ControlLoopTargetType targetType) { - this.targetType = targetType; - } - - public String getTarget() { - return target; - } - - public void setTarget(String target) { - this.target = target; - } - - public String getFrom() { - return from; - } - - public void setFrom(String from) { - this.from = from; - } - - public String getPolicyScope() { - return policyScope; - } - - public void setPolicyScope(String policyScope) { - this.policyScope = policyScope; - } - - public String getPolicyName() { - return policyName; - } - - public void setPolicyName(String policyName) { - this.policyName = policyName; - } - - public String getPolicyVersion() { - return policyVersion; - } - - public void setPolicyVersion(String policyVersion) { - this.policyVersion = policyVersion; - } - - public ControlLoopNotificationType getNotification() { - return notification; - } - - public void setNotification(ControlLoopNotificationType notification) { - this.notification = notification; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public ZonedDateTime getNotificationTime() { - return notificationTime; - } - - public void setNotificationTime(ZonedDateTime notificationTime) { - this.notificationTime = notificationTime; - } - - public Integer getOpsClTimer() { - return opsClTimer; - } - - public void setOpsClTimer(Integer opsClTimer) { - this.opsClTimer = opsClTimer; - } - - public List getHistory() { - return history; - } - - public void setHistory(List history) { - this.history = history; - } } diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java index fda0d0831..1ca182563 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopTargetType.java @@ -21,40 +21,9 @@ package org.onap.policy.controlloop; -public enum ControlLoopTargetType { - VM("VM"), VF("VF"), VFC("VFC"), VNF("VNF"); - - private String type; - - private ControlLoopTargetType(String type) { - this.type = type; - } - - @Override - public String toString() { - return this.type; - } - - /** - * Convert a String type to a ControlLoopTargetType. - * - * @param type the String type - * @return the ControlLoopTargetType - */ - public static ControlLoopTargetType toType(String type) { - if (VM.toString().equals(type)) { - return VM; - } - if (VF.toString().equals(type)) { - return VF; - } - if (VFC.toString().equals(type)) { - return VFC; - } - if (VNF.toString().equals(type)) { - return VNF; - } - - return null; - } +public class ControlLoopTargetType { + public static final String VM = "VM"; + public static final String VF = "VF"; + public static final String VFC = "VFC"; + public static final String VNF = "VNF"; } diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java index 1a0969189..43026a202 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/VirtualControlLoopEvent.java @@ -26,17 +26,24 @@ import com.google.gson.annotations.SerializedName; import java.time.Instant; import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter public class VirtualControlLoopEvent extends ControlLoopEvent { private static final long serialVersionUID = -5752405682246066226L; - + + @SerializedName("payload") + private String payload; + @SerializedName("closedLoopAlarmStart") private Instant closedLoopAlarmStart; - + @SerializedName("closedLoopAlarmEnd") private Instant closedLoopAlarmEnd; - + @SerializedName("AAI") private Map aai = new HashMap<>(); @@ -56,31 +63,8 @@ public class VirtualControlLoopEvent extends ControlLoopEvent { if (event.aai != null) { this.aai = new HashMap<>(event.aai); } + this.payload = event.payload; this.closedLoopAlarmStart = event.closedLoopAlarmStart; this.closedLoopAlarmEnd = event.closedLoopAlarmEnd; } - - public Instant getClosedLoopAlarmStart() { - return closedLoopAlarmStart; - } - - public void setClosedLoopAlarmStart(Instant closedLoopAlarmStart) { - this.closedLoopAlarmStart = closedLoopAlarmStart; - } - - public Instant getClosedLoopAlarmEnd() { - return closedLoopAlarmEnd; - } - - public void setClosedLoopAlarmEnd(Instant closedLoopAlarmEnd) { - this.closedLoopAlarmEnd = closedLoopAlarmEnd; - } - - public Map getAai() { - return aai; - } - - public void setAai(Map aai) { - this.aai = aai; - } } diff --git a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java index df7dc54d3..96797ed00 100644 --- a/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java +++ b/models-interactions/model-impl/events/src/main/java/org/onap/policy/controlloop/util/Serialization.java @@ -36,7 +36,6 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import org.onap.policy.controlloop.ControlLoopNotificationType; -import org.onap.policy.controlloop.ControlLoopTargetType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,19 +44,19 @@ public final class Serialization { new GsonBuilder().disableHtmlEscaping().registerTypeAdapter(ZonedDateTime.class, new GsonUtcAdapter()) .registerTypeAdapter(Instant.class, new GsonInstantAdapter()) .registerTypeAdapter(ControlLoopNotificationType.class, new NotificationTypeAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()).create(); + .create(); public static final Gson gsonPretty = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() .registerTypeAdapter(ZonedDateTime.class, new GsonUtcAdapter()) .registerTypeAdapter(Instant.class, new GsonInstantAdapter()) .registerTypeAdapter(ControlLoopNotificationType.class, new NotificationTypeAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()).create(); + .create(); public static final Gson gsonJunit = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting() .registerTypeAdapter(ZonedDateTime.class, new GsonUtcAdapter()) .registerTypeAdapter(Instant.class, new GsonInstantAdapter()) - .registerTypeAdapter(ControlLoopTargetType.class, new TargetTypeAdapter()).create(); + .create(); private Serialization() {} @@ -76,19 +75,6 @@ public final class Serialization { } } - public static class TargetTypeAdapter - implements JsonSerializer, JsonDeserializer { - @Override - public JsonElement serialize(ControlLoopTargetType src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.toString()); - } - - @Override - public ControlLoopTargetType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { - return ControlLoopTargetType.toType(json.getAsString()); - } - } - public static class GsonUtcAdapter implements JsonSerializer, JsonDeserializer { private static final Logger logger = LoggerFactory.getLogger(GsonUtcAdapter.class); public static final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSxxx"); diff --git a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopEventTest.java b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopEventTest.java index feaf22ee5..2def97572 100644 --- a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopEventTest.java +++ b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopEventTest.java @@ -63,9 +63,6 @@ public class ControlLoopEventTest { event.setFrom("from"); assertEquals("from", event.getFrom()); - event.setPayload("payload"); - assertEquals("payload", event.getPayload()); - event.setPolicyName("policyname"); assertEquals("policyname", event.getPolicyName()); diff --git a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java index d1412fe49..3434a591b 100644 --- a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java +++ b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopTargetTypeTest.java @@ -30,11 +30,9 @@ public class ControlLoopTargetTypeTest { @Test public void test() { - assertEquals(ControlLoopTargetType.VM, ControlLoopTargetType.toType("VM")); - assertEquals(ControlLoopTargetType.VF, ControlLoopTargetType.toType("VF")); - assertEquals(ControlLoopTargetType.VFC, ControlLoopTargetType.toType("VFC")); - assertEquals(ControlLoopTargetType.VNF, ControlLoopTargetType.toType("VNF")); - - assertNull(ControlLoopTargetType.toType("foo")); + assertEquals("VM", ControlLoopTargetType.VM); + assertEquals("VF", ControlLoopTargetType.VF); + assertEquals("VFC", ControlLoopTargetType.VFC); + assertEquals("VNF", ControlLoopTargetType.VNF); } } diff --git a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/VirtualControlLoopEventTest.java b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/VirtualControlLoopEventTest.java index 2acd3038c..3fc7d133e 100644 --- a/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/VirtualControlLoopEventTest.java +++ b/models-interactions/model-impl/events/src/test/java/org/onap/policy/controlloop/VirtualControlLoopEventTest.java @@ -37,6 +37,9 @@ public class VirtualControlLoopEventTest { assertNotNull(event); assertNotNull(event.getAai()); + event.setPayload("payload"); + assertEquals("payload", event.getPayload()); + Instant now = Instant.now(); event.setClosedLoopAlarmStart(now); event.setClosedLoopAlarmEnd(now); diff --git a/models-interactions/model-impl/rest/src/main/java/org/onap/policy/rest/RestManager.java b/models-interactions/model-impl/rest/src/main/java/org/onap/policy/rest/RestManager.java index 643c629b3..dde3aa2e2 100644 --- a/models-interactions/model-impl/rest/src/main/java/org/onap/policy/rest/RestManager.java +++ b/models-interactions/model-impl/rest/src/main/java/org/onap/policy/rest/RestManager.java @@ -29,6 +29,7 @@ import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; @@ -171,6 +172,33 @@ public class RestManager { return sendRequest(delete); } + /** + * Perform REST Patch. + * + * @param url the url + * @param username the user name + * @param password the password + * @param headers any headers + * @param body body to send + * @return the response status code and the body + */ + public Pair patch(String url, String username, String password, + Map headers, String body) { + String contentType = "application/merge-patch+json"; + HttpPatch patch = new HttpPatch(url); + addHeaders(patch, username, password, headers); + patch.addHeader(CONTENT_TYPE, contentType); + try { + StringEntity input = new StringEntity(body); + input.setContentType(contentType); + patch.setEntity(input); + } catch (Exception e) { + logger.error("patch threw: ", e); + return null; + } + return sendRequest(patch); + } + /** * Send REST request. * diff --git a/models-interactions/model-impl/rest/src/test/java/org/onap/policy/rest/RestTest.java b/models-interactions/model-impl/rest/src/test/java/org/onap/policy/rest/RestTest.java index 903ec2fa3..21a971651 100644 --- a/models-interactions/model-impl/rest/src/test/java/org/onap/policy/rest/RestTest.java +++ b/models-interactions/model-impl/rest/src/test/java/org/onap/policy/rest/RestTest.java @@ -24,10 +24,17 @@ package org.onap.policy.rest; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; +import javax.ws.rs.HttpMethod; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -45,7 +52,7 @@ import org.onap.policy.rest.RestManager.Pair; @Path("RestTest") public class RestTest { - + private static final String MERGE_PATCH_PLUS_JSON = "application/merge-patch+json"; private static final String NAME_PARAM = "Bob"; private static final String AGE_PARAM = "10"; @@ -64,6 +71,8 @@ public class RestTest { private static String putUriBlank; private static String postUri; private static String postUriBlank; + private static String patchUri; + private static String patchUriBlank; private static HttpServletServer server; @@ -81,6 +90,8 @@ public class RestTest { putUriBlank = baseUri + "RestTest/PutBlank"; postUri = baseUri + "RestTest/PostHello/" + NAME_PARAM + "?age=" + AGE_PARAM; postUriBlank = baseUri + "RestTest/PostBlank"; + patchUri = baseUri + "RestTest/PatchHello/" + NAME_PARAM + "?age=" + AGE_PARAM; + patchUriBlank = baseUri + "RestTest/PatchBlank"; server = HttpServletServerFactoryInstance.getServerFactory() .build("RestTest", LOCALHOST, port, "/" + BASE, false, true); @@ -123,6 +134,12 @@ public class RestTest { mgr.delete(null, "user", null, null, null, null); } + @Test(expected = NullPointerException.class) + public void testPatchUrlNull() { + RestManager mgr = new RestManager(); + mgr.patch(null, "user", null, null, PAYLOAD); + } + @Test public void testUsernameNull() { RestManager mgr = new RestManager(); @@ -168,6 +185,18 @@ public class RestTest { assertTrue(result.second != null); assertTrue(result.second.length() > 0); assertEquals("POST: " + PAYLOAD + RETURN_STRING, result.second); + + result = mgr.patch(patchUri, null, null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + EXPECT_STRING, result.second); + + result = mgr.patch(patchUriBlank, null, null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + RETURN_STRING, result.second); } @Test @@ -209,6 +238,18 @@ public class RestTest { assertTrue(result.second != null); assertTrue(result.second.length() > 0); assertEquals("POST: " + PAYLOAD + RETURN_STRING, result.second); + + result = mgr.patch(patchUri, "", null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + EXPECT_STRING, result.second); + + result = mgr.patch(patchUriBlank, "", null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + RETURN_STRING, result.second); } @Test @@ -250,6 +291,18 @@ public class RestTest { assertTrue(result.second != null); assertTrue(result.second.length() > 0); assertEquals("POST: " + PAYLOAD + RETURN_STRING, result.second); + + result = mgr.patch(patchUri, "user", null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + EXPECT_STRING, result.second); + + result = mgr.patch(patchUriBlank, "user", null, null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + RETURN_STRING, result.second); } @Test @@ -267,6 +320,9 @@ public class RestTest { result = mgr.post(baseUri + "RestTest/PostHello/", null, null, null, MediaType.TEXT_PLAIN, PAYLOAD); assertEquals((Integer)404, result.first); + + result = mgr.patch(baseUri + "RestTest/PatchHello/", null, null, null, PAYLOAD); + assertEquals((Integer)404, result.first); } @Test @@ -297,6 +353,13 @@ public class RestTest { assertTrue(result.second != null); assertTrue(result.second.length() > 0); assertEquals("POST: " + PAYLOAD + RETURN_STRING + NAME_PARAM + " aged 90", result.second); + + result = mgr.patch(baseUri + "RestTest/PatchHello/" + NAME_PARAM, null, null, + null, PAYLOAD); + assertEquals((Integer)200, result.first); + assertTrue(result.second != null); + assertTrue(result.second.length() > 0); + assertEquals("PATCH: " + PAYLOAD + RETURN_STRING + NAME_PARAM + " aged 90", result.second); } @Test @@ -314,6 +377,9 @@ public class RestTest { result = mgr.post(baseUri + "NonExistant/URL/", null, null, null, MediaType.TEXT_PLAIN, PAYLOAD); assertEquals((Integer)404, result.first); + + result = mgr.patch(baseUri + "NonExistant/URL/", null, null, null, PAYLOAD); + assertEquals((Integer)404, result.first); } @Test @@ -334,6 +400,9 @@ public class RestTest { result = mgr.post(getUri, null, null, null, MediaType.TEXT_PLAIN, PAYLOAD); assertEquals((Integer)405, result.first); + + result = mgr.patch(getUri, null, null, null, PAYLOAD); + assertEquals((Integer)405, result.first); } @GET @@ -387,4 +456,30 @@ public class RestTest { public String postBlank( String payload) { return "POST: " + payload + RETURN_STRING; } + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + @HttpMethod("PATCH") + @Documented + public static @interface Patch { + } + + @Patch + @Path("/PatchHello/{name}") + @Consumes(MERGE_PATCH_PLUS_JSON) + @Produces(MERGE_PATCH_PLUS_JSON) + public String patchIt( + String payload, + @PathParam("name") String name, + @DefaultValue("90") @QueryParam("age") String age) { + + return "PATCH: " + payload + RETURN_STRING + name + " aged " + age; + } + + @Patch + @Path("/PatchBlank") + @Produces(MERGE_PATCH_PLUS_JSON) + public String patchBlank( String payload) { + return "PATCH: " + payload + RETURN_STRING; + } }