From 7dd46a20a91e74654c58957d839694b17b865043 Mon Sep 17 00:00:00 2001 From: Sina Madani Date: Tue, 15 Oct 2024 12:26:37 +0100 Subject: [PATCH] feat: Add Network capability to Application (#545) * feat: Add Network APIs to Application * Bump versions * Test network_apis --- CHANGELOG.md | 4 + pom.xml | 14 +- .../java/com/vonage/client/HttpWrapper.java | 2 +- .../client/application/Application.java | 19 ++- .../application/capabilities/Capability.java | 9 +- .../application/capabilities/NetworkApis.java | 121 ++++++++++++++++++ .../client/application/capabilities/Vbc.java | 1 - .../client/messages/InboundMessage.java | 1 + .../vonage/client/messages/MessageStatus.java | 1 + .../com/vonage/client/sms/MessageEvent.java | 2 + .../client/verify2/VerificationCallback.java | 2 + .../vonage/client/voice/AnswerWebhook.java | 2 + .../com/vonage/client/voice/EventWebhook.java | 2 + .../application/ApplicationClientTest.java | 10 ++ .../client/application/ApplicationTest.java | 31 ++++- .../insight/StandardInsightResponseTest.java | 1 - 16 files changed, 203 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/vonage/client/application/capabilities/NetworkApis.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca53ba5e..7ec81347b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +# [8.12.0] - 2024-10-?? +- Added `network_apis` capability to Application API +- Added `@JsonCreator` annotation to webhook classes' `fromJson(String)` method + # [8.11.0] - 2024-09-25 - Added custom user agent property setting to `HttpConfig` - Added RCS channel to Messages API diff --git a/pom.xml b/pom.xml index 7f1b9b9fd..42c1e7aba 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.vonage server-sdk - 8.11.0 + 8.12.0 Vonage Java Server SDK Java client for Vonage APIs @@ -45,7 +45,7 @@ 21 UTF-8 https://oss.sonatype.org - 2.17.2 + 2.18.0 0.12.6 @@ -86,13 +86,13 @@ org.junit.jupiter junit-jupiter-engine - 5.11.0 + 5.11.2 test org.mockito mockito-core - 5.13.0 + 5.14.1 test @@ -190,7 +190,7 @@ maven-surefire-plugin - 3.5.0 + 3.5.1 @@ -228,7 +228,7 @@ maven-javadoc-plugin - 3.10.0 + 3.10.1 true @@ -291,7 +291,7 @@ maven-gpg-plugin - 3.2.6 + 3.2.7 sign-artifacts diff --git a/src/main/java/com/vonage/client/HttpWrapper.java b/src/main/java/com/vonage/client/HttpWrapper.java index cbc700173..91cb6bcfd 100644 --- a/src/main/java/com/vonage/client/HttpWrapper.java +++ b/src/main/java/com/vonage/client/HttpWrapper.java @@ -34,7 +34,7 @@ public class HttpWrapper { private static final String CLIENT_NAME = "vonage-java-sdk", - CLIENT_VERSION = "8.11.0", + CLIENT_VERSION = "8.12.0", JAVA_VERSION = System.getProperty("java.version"), USER_AGENT = String.format("%s/%s java/%s", CLIENT_NAME, CLIENT_VERSION, JAVA_VERSION); diff --git a/src/main/java/com/vonage/client/application/Application.java b/src/main/java/com/vonage/client/application/Application.java index 8995c0f77..0d5f079d0 100644 --- a/src/main/java/com/vonage/client/application/Application.java +++ b/src/main/java/com/vonage/client/application/Application.java @@ -206,7 +206,8 @@ public Builder removeCapability(Capability.Type type) { capabilities.rtc == null && capabilities.messages == null && capabilities.vbc == null && - capabilities.verify == null + capabilities.verify == null && + capabilities.networkApis == null ) { capabilities = null; } @@ -278,6 +279,7 @@ public static class Capabilities extends JsonableBaseObject { private Rtc rtc; private Vbc vbc; private Verify verify; + private NetworkApis networkApis; /** * Voice capability. @@ -323,7 +325,6 @@ public Vbc getVbc() { * Verify capability. * * @return The Verify capability, or {@code null} if absent. - * * @since 8.6.0 */ @JsonProperty("verify") @@ -331,6 +332,17 @@ public Verify getVerify() { return verify; } + /** + * Network APIs capability. + * + * @return The Network APIs capability, or {@code null} if absent. + * @since 8.12.0 + */ + @JsonProperty("network_apis") + public NetworkApis getNetworkApis() { + return networkApis; + } + private void setCapability(Capability.Type type, Capability capability) { switch (type) { case VOICE: @@ -348,6 +360,9 @@ private void setCapability(Capability.Type type, Capability capability) { case VERIFY: verify = (Verify) capability; break; + case NETWORK: + networkApis = (NetworkApis) capability; + break; } } diff --git a/src/main/java/com/vonage/client/application/capabilities/Capability.java b/src/main/java/com/vonage/client/application/capabilities/Capability.java index aef9d90b2..ebaa307c7 100644 --- a/src/main/java/com/vonage/client/application/capabilities/Capability.java +++ b/src/main/java/com/vonage/client/application/capabilities/Capability.java @@ -86,7 +86,14 @@ public enum Type { * * @since 8.6.0 */ - VERIFY + VERIFY, + + /** + * Network APIs + * + * @since 8.12.0 + */ + NETWORK } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/vonage/client/application/capabilities/NetworkApis.java b/src/main/java/com/vonage/client/application/capabilities/NetworkApis.java new file mode 100644 index 000000000..503114292 --- /dev/null +++ b/src/main/java/com/vonage/client/application/capabilities/NetworkApis.java @@ -0,0 +1,121 @@ +/* + * Copyright 2024 Vonage + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.vonage.client.application.capabilities; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.net.URI; + +/** + * Network APIs capability configuration settings. + * + * @since 8.12.0 + */ +public final class NetworkApis extends Capability { + private URI redirectUri; + private String networkApplicationId; + + private NetworkApis() { + } + + private NetworkApis(Builder builder) { + super(builder); + redirectUri = builder.redirectUri; + networkApplicationId = builder.networkApplicationId; + } + + @Override + public Type getType() { + return Type.NETWORK; + } + + /** + * Gets the Redirect URL. + * + * @return The redirect URI, or {@code null} if absent. + */ + @JsonProperty("redirect_uri") + public URI getRedirectUri() { + return redirectUri; + } + + /** + * Gets the network application ID (this is different from the Vonage application ID). + * + * @return The network application ID as a string, or {@code null} if absent. + */ + @JsonProperty("network_application_id") + public String getNetworkApplicationId() { + return networkApplicationId; + } + + /** + * Entry point for constructing an instance of this class. + * + * @return A new Builder. + */ + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends Capability.Builder { + private URI redirectUri; + private String networkApplicationId; + + private Builder() {} + + /** + * Sets the Redirect URL. + * + * @param redirectUri The redirect URL as a string. + * @return This builder. + */ + public Builder redirectUri(String redirectUri) { + return redirectUri(URI.create(redirectUri)); + } + + /** + * Sets the Redirect URL. + * + * @param redirectUri The redirect URL. + * @return This builder. + */ + public Builder redirectUri(URI redirectUri) { + this.redirectUri = redirectUri; + return this; + } + + /** + * Sets the network application ID (this is different from the Vonage application ID). + * + * @param networkApplicationId The network application ID as a string. + * @return This builder. + */ + public Builder networkApplicationId(String networkApplicationId) { + this.networkApplicationId = networkApplicationId; + return this; + } + + /** + * Builds the NetworkApis object. + * + * @return A new Network APIs capability. + */ + @Override + public NetworkApis build() { + return new NetworkApis(this); + } + } +} diff --git a/src/main/java/com/vonage/client/application/capabilities/Vbc.java b/src/main/java/com/vonage/client/application/capabilities/Vbc.java index ce03ba44f..fad6d0fbe 100644 --- a/src/main/java/com/vonage/client/application/capabilities/Vbc.java +++ b/src/main/java/com/vonage/client/application/capabilities/Vbc.java @@ -15,7 +15,6 @@ */ package com.vonage.client.application.capabilities; - /** * VBC capability configuration settings. */ diff --git a/src/main/java/com/vonage/client/messages/InboundMessage.java b/src/main/java/com/vonage/client/messages/InboundMessage.java index 82087f961..e9d867abd 100644 --- a/src/main/java/com/vonage/client/messages/InboundMessage.java +++ b/src/main/java/com/vonage/client/messages/InboundMessage.java @@ -434,6 +434,7 @@ public List getContent() { * @return The deserialized webhook response object. * @throws com.vonage.client.VonageResponseParseException If the response could not be deserialized. */ + @JsonCreator public static InboundMessage fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/main/java/com/vonage/client/messages/MessageStatus.java b/src/main/java/com/vonage/client/messages/MessageStatus.java index 8176779e4..ecfdde2a6 100644 --- a/src/main/java/com/vonage/client/messages/MessageStatus.java +++ b/src/main/java/com/vonage/client/messages/MessageStatus.java @@ -330,6 +330,7 @@ public String getWhatsappConversationId() { * * @return An instance of this class with the fields populated, if present. */ + @JsonCreator public static MessageStatus fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/main/java/com/vonage/client/sms/MessageEvent.java b/src/main/java/com/vonage/client/sms/MessageEvent.java index 9480d7f66..5aece2e98 100644 --- a/src/main/java/com/vonage/client/sms/MessageEvent.java +++ b/src/main/java/com/vonage/client/sms/MessageEvent.java @@ -15,6 +15,7 @@ */ package com.vonage.client.sms; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import com.vonage.client.Jsonable; @@ -198,6 +199,7 @@ public Integer getConcatPart() { * * @return An instance of this class with the fields populated, if present. */ + @JsonCreator public static MessageEvent fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/main/java/com/vonage/client/verify2/VerificationCallback.java b/src/main/java/com/vonage/client/verify2/VerificationCallback.java index 988bd246d..a0e5c848b 100644 --- a/src/main/java/com/vonage/client/verify2/VerificationCallback.java +++ b/src/main/java/com/vonage/client/verify2/VerificationCallback.java @@ -15,6 +15,7 @@ */ package com.vonage.client.verify2; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.vonage.client.Jsonable; @@ -176,6 +177,7 @@ public URI getSilentAuthUrl() { * @return The deserialized webhook response object. * @throws VonageResponseParseException If the response could not be deserialized. */ + @JsonCreator public static VerificationCallback fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/main/java/com/vonage/client/voice/AnswerWebhook.java b/src/main/java/com/vonage/client/voice/AnswerWebhook.java index c969277f1..177d53730 100644 --- a/src/main/java/com/vonage/client/voice/AnswerWebhook.java +++ b/src/main/java/com/vonage/client/voice/AnswerWebhook.java @@ -15,6 +15,7 @@ */ package com.vonage.client.voice; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.vonage.client.Jsonable; @@ -107,6 +108,7 @@ public URI getRegionUrl() { * * @return A new instance of this class. */ + @JsonCreator public static AnswerWebhook fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/main/java/com/vonage/client/voice/EventWebhook.java b/src/main/java/com/vonage/client/voice/EventWebhook.java index f7aa7ebdc..ef75e7d18 100644 --- a/src/main/java/com/vonage/client/voice/EventWebhook.java +++ b/src/main/java/com/vonage/client/voice/EventWebhook.java @@ -16,6 +16,7 @@ package com.vonage.client.voice; import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.vonage.client.Jsonable; import com.vonage.client.JsonableBaseObject; @@ -292,6 +293,7 @@ public String getReason() { * * @return A new instance of this class. */ + @JsonCreator public static EventWebhook fromJson(String json) { return Jsonable.fromJson(json); } diff --git a/src/test/java/com/vonage/client/application/ApplicationClientTest.java b/src/test/java/com/vonage/client/application/ApplicationClientTest.java index 4796d6b96..9a18c0acf 100644 --- a/src/test/java/com/vonage/client/application/ApplicationClientTest.java +++ b/src/test/java/com/vonage/client/application/ApplicationClientTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.function.Executable; +import java.net.URI; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -73,6 +74,10 @@ public class ApplicationClientTest extends AbstractClientTest " }\n" + " }\n" + " },\n" + + " \"network_apis\": {\n" + + " \"network_application_id\": \"2bzfIFqRG128IcjSj1YhZNtw6LADG\",\n" + + " \"redirect_uri\": \"https://my-redirect-uri.example.com\"\n" + + " },\n" + " \"rtc\": {\n" + " \"webhooks\": {\n" + " \"event_url\": {\n" + @@ -133,6 +138,11 @@ static void assertEqualsSampleApplication(Application response) { assertEquals("https://example.com/webhooks/status", message.getWebhooks().get(Webhook.Type.STATUS).getAddress()); assertEquals(HttpMethod.POST, message.getWebhooks().get(Webhook.Type.STATUS).getMethod()); + NetworkApis networkApis = capabilities.getNetworkApis(); + assertEquals(Capability.Type.NETWORK, networkApis.getType()); + assertEquals("2bzfIFqRG128IcjSj1YhZNtw6LADG", networkApis.getNetworkApplicationId()); + assertEquals(URI.create("https://my-redirect-uri.example.com"), networkApis.getRedirectUri()); + Rtc rtc = capabilities.getRtc(); assertEquals(Capability.Type.RTC, rtc.getType()); assertEquals("https://example.com/webhooks/event", rtc.getWebhooks().get(Webhook.Type.EVENT).getAddress()); diff --git a/src/test/java/com/vonage/client/application/ApplicationTest.java b/src/test/java/com/vonage/client/application/ApplicationTest.java index 6f6f31788..a7842e2ef 100644 --- a/src/test/java/com/vonage/client/application/ApplicationTest.java +++ b/src/test/java/com/vonage/client/application/ApplicationTest.java @@ -167,17 +167,36 @@ public void testAddVerifyCapabilityWithStatusWebhooks() { @Test public void testAddMessagesCapabilityWithInboundWebhook() { String json = "{\"capabilities\":{\"messages\":{\"webhooks\":{\"inbound_url\":{\"address\":\"https://example.com/inbound\",\"http_method\":\"POST\"}}}}}"; - Application application = Application.builder() - .addCapability( - Messages.builder() - .addWebhook(Webhook.Type.INBOUND, new Webhook("https://example.com/inbound", HttpMethod.POST)) - .build()) - .build(); + Application application = Application.builder().addCapability( + Messages.builder() + .addWebhook(Webhook.Type.INBOUND, new Webhook("https://example.com/inbound", HttpMethod.POST)) + .build() + ) + .build(); assertEquals(json, application.toJson()); testJsonableBaseObject(application); } + @Test + public void testAddNetworkApisCapabilityWithRedirectUriAndId() { + String redirectUri = "http://localhost:8080/camara/redirect", + networkApplicationId = "my-network-application-id", + expectedJson = "{\"capabilities\":{\"network_apis\":{\"redirect_uri\":\"" + + redirectUri + "\",\"network_application_id\":\""+networkApplicationId+"\"}}}"; + + Application application = Application.builder().addCapability( + NetworkApis.builder() + .redirectUri(redirectUri) + .networkApplicationId(networkApplicationId) + .build() + ) + .build(); + + testJsonableBaseObject(application); + assertEquals(expectedJson, application.toJson()); + } + @Test public void testUpdatingApplication() { String json = "{\"name\":\"updated\"}"; diff --git a/src/test/java/com/vonage/client/insight/StandardInsightResponseTest.java b/src/test/java/com/vonage/client/insight/StandardInsightResponseTest.java index d4b29964f..688abf543 100644 --- a/src/test/java/com/vonage/client/insight/StandardInsightResponseTest.java +++ b/src/test/java/com/vonage/client/insight/StandardInsightResponseTest.java @@ -59,7 +59,6 @@ public void testFromJson() { " }\n" + "}"); - TestUtils.testJsonableBaseObject(response); assertEquals(InsightStatus.LOOKUP_NOT_RETURNED, response.getStatus()); assertEquals(43, response.getStatus().getInsightStatus()); assertEquals("Lookup not returned", response.getStatusMessage());