From 8be4d678721e1d3fd76551dca63a83fecb2f2ad5 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Tue, 29 May 2018 12:31:29 -0400 Subject: [PATCH 01/21] Re-add development heading to CHANGELOG. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b78760bdc..d50659ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Development] + ## [3.5.0] - 2018-05-29 ### Changed - Updated `VerifyClient` to use the JSON endpoints instead of XML. From 8e690301d1448265821bff9bec4f841502937b72 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 1 Jun 2018 12:11:36 -0400 Subject: [PATCH 02/21] Move ClientTest from the verify package so it can be shared with other client tests. --- src/test/java/com/nexmo/client/{verify => }/ClientTest.java | 4 +--- .../nexmo/client/verify/VerifyClientCheckEndpointTest.java | 1 + .../nexmo/client/verify/VerifyClientSearchEndpointTest.java | 1 + .../client/verify/VerifyClientVerifyControlEndpointTest.java | 1 + .../nexmo/client/verify/VerifyClientVerifyEndpointTest.java | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) rename src/test/java/com/nexmo/client/{verify => }/ClientTest.java (95%) diff --git a/src/test/java/com/nexmo/client/verify/ClientTest.java b/src/test/java/com/nexmo/client/ClientTest.java similarity index 95% rename from src/test/java/com/nexmo/client/verify/ClientTest.java rename to src/test/java/com/nexmo/client/ClientTest.java index af131db56..f71ead57a 100644 --- a/src/test/java/com/nexmo/client/verify/ClientTest.java +++ b/src/test/java/com/nexmo/client/ClientTest.java @@ -19,10 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.nexmo.client.verify; +package com.nexmo.client; -import com.nexmo.client.AbstractClient; -import com.nexmo.client.HttpWrapper; import com.nexmo.client.auth.TokenAuthMethod; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; diff --git a/src/test/java/com/nexmo/client/verify/VerifyClientCheckEndpointTest.java b/src/test/java/com/nexmo/client/verify/VerifyClientCheckEndpointTest.java index 154c9bebf..0d9c88594 100644 --- a/src/test/java/com/nexmo/client/verify/VerifyClientCheckEndpointTest.java +++ b/src/test/java/com/nexmo/client/verify/VerifyClientCheckEndpointTest.java @@ -21,6 +21,7 @@ */ package com.nexmo.client.verify; +import com.nexmo.client.ClientTest; import com.nexmo.client.NexmoResponseParseException; import org.junit.Assert; import org.junit.Before; diff --git a/src/test/java/com/nexmo/client/verify/VerifyClientSearchEndpointTest.java b/src/test/java/com/nexmo/client/verify/VerifyClientSearchEndpointTest.java index 153733e47..20bbce918 100644 --- a/src/test/java/com/nexmo/client/verify/VerifyClientSearchEndpointTest.java +++ b/src/test/java/com/nexmo/client/verify/VerifyClientSearchEndpointTest.java @@ -21,6 +21,7 @@ */ package com.nexmo.client.verify; +import com.nexmo.client.ClientTest; import com.nexmo.client.NexmoResponseParseException; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/nexmo/client/verify/VerifyClientVerifyControlEndpointTest.java b/src/test/java/com/nexmo/client/verify/VerifyClientVerifyControlEndpointTest.java index caeceb2cd..1f7893914 100644 --- a/src/test/java/com/nexmo/client/verify/VerifyClientVerifyControlEndpointTest.java +++ b/src/test/java/com/nexmo/client/verify/VerifyClientVerifyControlEndpointTest.java @@ -21,6 +21,7 @@ */ package com.nexmo.client.verify; +import com.nexmo.client.ClientTest; import org.junit.Assert; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/nexmo/client/verify/VerifyClientVerifyEndpointTest.java b/src/test/java/com/nexmo/client/verify/VerifyClientVerifyEndpointTest.java index 8cdd139f9..3e53ae445 100644 --- a/src/test/java/com/nexmo/client/verify/VerifyClientVerifyEndpointTest.java +++ b/src/test/java/com/nexmo/client/verify/VerifyClientVerifyEndpointTest.java @@ -21,6 +21,7 @@ */ package com.nexmo.client.verify; +import com.nexmo.client.ClientTest; import org.junit.Before; import org.junit.Test; From 99f2adecb1a61bc804681bd469067614dab4b514 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 1 Jun 2018 12:13:33 -0400 Subject: [PATCH 03/21] Add data models for deserializing json response when getting pricing. --- .../com/nexmo/client/account/Country.java | 47 +++++++++ .../com/nexmo/client/account/Network.java | 96 +++++++++++++++++++ .../nexmo/client/account/PricingResponse.java | 69 +++++++++++++ .../com/nexmo/client/account/ServiceType.java | 26 +++++ 4 files changed, 238 insertions(+) create mode 100644 src/main/java/com/nexmo/client/account/Country.java create mode 100644 src/main/java/com/nexmo/client/account/Network.java create mode 100644 src/main/java/com/nexmo/client/account/PricingResponse.java create mode 100644 src/main/java/com/nexmo/client/account/ServiceType.java diff --git a/src/main/java/com/nexmo/client/account/Country.java b/src/main/java/com/nexmo/client/account/Country.java new file mode 100644 index 000000000..ec261fdcb --- /dev/null +++ b/src/main/java/com/nexmo/client/account/Country.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Country { + private String code; + private String displayName; + private String name; + + @JsonProperty("countryCode") + public String getCode() { + return code; + } + + @JsonProperty("countryDisplayName") + public String getDisplayName() { + return displayName; + } + + @JsonProperty("countryName") + public String getName() { + return name; + } +} diff --git a/src/main/java/com/nexmo/client/account/Network.java b/src/main/java/com/nexmo/client/account/Network.java new file mode 100644 index 000000000..386a17db6 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/Network.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Network { + private Type type; + private BigDecimal price; + private String currency; + private String mcc; + private String mnc; + private String code; + private String name; + + public Type getType() { + return type; + } + + public BigDecimal getPrice() { + return price; + } + + public String getCurrency() { + return currency; + } + + public String getMcc() { + return mcc; + } + + public String getMnc() { + return mnc; + } + + @JsonProperty("networkCode") + public String getCode() { + return code; + } + + @JsonProperty("networkName") + public String getName() { + return name; + } + + enum Type { + MOBILE, LANDLINE, PAGER, LANDLINE_TOLLFREE, UNKNOWN; + + private static final Map typesIndex = new HashMap<>(); + + static { + for (Type type : Type.values()) { + typesIndex.put(type.toString(), type); + } + } + + @Override + @JsonValue + public String toString() { + return name().toLowerCase(); + } + + @JsonCreator + public static Type fromString(String type) { + Type foundType = typesIndex.get(type); + return (foundType != null) ? foundType : Type.UNKNOWN; + } + } +} diff --git a/src/main/java/com/nexmo/client/account/PricingResponse.java b/src/main/java/com/nexmo/client/account/PricingResponse.java new file mode 100644 index 000000000..9f8cc5e3c --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PricingResponse.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class PricingResponse { + private String dialingPrefix; + private BigDecimal defaultPrice; + private String currency; + @JsonUnwrapped + private Country country; + private List networks; + + public String getDialingPrefix() { + return dialingPrefix; + } + + public BigDecimal getDefaultPrice() { + return defaultPrice; + } + + public String getCurrency() { + return currency; + } + + public Country getCountry() { + return country; + } + + public List getNetworks() { + return networks; + } + + public static PricingResponse fromJson(String json) { + try { + return new ObjectMapper().readValue(json, PricingResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce PricingResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/account/ServiceType.java b/src/main/java/com/nexmo/client/account/ServiceType.java new file mode 100644 index 000000000..22534ae38 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/ServiceType.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +public enum ServiceType { + SMS, VOICE; +} From 8904630fc46eb5c8bca68fb182e25d484b67dad8 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 1 Jun 2018 12:15:14 -0400 Subject: [PATCH 04/21] Add pricing methods and endpoints for getting SMS and voice prices. --- .../nexmo/client/account/PricingEndpoint.java | 46 +++++++++++++++ .../nexmo/client/account/PricingMethod.java | 56 +++++++++++++++++++ .../nexmo/client/account/PricingRequest.java | 34 +++++++++++ .../client/account/SmsPricingMethod.java | 39 +++++++++++++ .../client/account/VoicePricingMethod.java | 39 +++++++++++++ 5 files changed, 214 insertions(+) create mode 100644 src/main/java/com/nexmo/client/account/PricingEndpoint.java create mode 100644 src/main/java/com/nexmo/client/account/PricingMethod.java create mode 100644 src/main/java/com/nexmo/client/account/PricingRequest.java create mode 100644 src/main/java/com/nexmo/client/account/SmsPricingMethod.java create mode 100644 src/main/java/com/nexmo/client/account/VoicePricingMethod.java diff --git a/src/main/java/com/nexmo/client/account/PricingEndpoint.java b/src/main/java/com/nexmo/client/account/PricingEndpoint.java new file mode 100644 index 000000000..aff7065da --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PricingEndpoint.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +class PricingEndpoint { + private Map methods = new HashMap<>(); + + PricingEndpoint(HttpWrapper httpWrapper) { + this.methods.put(ServiceType.SMS, new SmsPricingMethod(httpWrapper)); + this.methods.put(ServiceType.VOICE, new VoicePricingMethod(httpWrapper)); + } + + PricingResponse getPrice(ServiceType serviceType, PricingRequest request) throws IOException, NexmoClientException { + if (this.methods.containsKey(serviceType)) { + return this.methods.get(serviceType).execute(request); + } + + throw new IllegalArgumentException("Unknown Service Type: " + serviceType); + } +} diff --git a/src/main/java/com/nexmo/client/account/PricingMethod.java b/src/main/java/com/nexmo/client/account/PricingMethod.java new file mode 100644 index 000000000..9529292d2 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PricingMethod.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.voice.endpoints.AbstractMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; + +import java.io.IOException; + +abstract class PricingMethod extends AbstractMethod { + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + PricingMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(PricingRequest pricingRequest) { + return RequestBuilder.get(this.getUri()).addParameter("country", pricingRequest.getCountryCode()); + } + + @Override + public PricingResponse parseResponse(HttpResponse response) throws IOException { + return PricingResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } + + abstract String getUri(); +} diff --git a/src/main/java/com/nexmo/client/account/PricingRequest.java b/src/main/java/com/nexmo/client/account/PricingRequest.java new file mode 100644 index 000000000..5d31b8d87 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PricingRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +public class PricingRequest { + private String countryCode; + + public PricingRequest(String countryCode) { + this.countryCode = countryCode; + } + + public String getCountryCode() { + return countryCode; + } +} diff --git a/src/main/java/com/nexmo/client/account/SmsPricingMethod.java b/src/main/java/com/nexmo/client/account/SmsPricingMethod.java new file mode 100644 index 000000000..68732fef2 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/SmsPricingMethod.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; + +public class SmsPricingMethod extends PricingMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/account/get-pricing/outbound/sms"; + + private String uri = DEFAULT_URI; + + SmsPricingMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + String getUri() { + return this.uri; + } +} diff --git a/src/main/java/com/nexmo/client/account/VoicePricingMethod.java b/src/main/java/com/nexmo/client/account/VoicePricingMethod.java new file mode 100644 index 000000000..a083e47c1 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/VoicePricingMethod.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; + +public class VoicePricingMethod extends PricingMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/account/get-pricing/outbound/voice"; + + private String uri = DEFAULT_URI; + + VoicePricingMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + String getUri() { + return this.uri; + } +} From 58e4b176e71126b5223136692c7e72b656131c7d Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 13 Jun 2018 13:27:36 -0400 Subject: [PATCH 05/21] Add prefix pricing. --- .../nexmo/client/account/AccountClient.java | 59 ++++++- .../client/account/PrefixPricingEndpoint.java | 39 +++++ .../client/account/PrefixPricingMethod.java | 59 +++++++ .../client/account/PrefixPricingRequest.java | 43 +++++ .../client/account/PrefixPricingResponse.java | 51 ++++++ .../client/account/AccountClientTest.java | 152 +++++++++++++++++- 6 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/nexmo/client/account/PrefixPricingEndpoint.java create mode 100644 src/main/java/com/nexmo/client/account/PrefixPricingMethod.java create mode 100644 src/main/java/com/nexmo/client/account/PrefixPricingRequest.java create mode 100644 src/main/java/com/nexmo/client/account/PrefixPricingResponse.java diff --git a/src/main/java/com/nexmo/client/account/AccountClient.java b/src/main/java/com/nexmo/client/account/AccountClient.java index 6f86466ba..72bd3d2a8 100644 --- a/src/main/java/com/nexmo/client/account/AccountClient.java +++ b/src/main/java/com/nexmo/client/account/AccountClient.java @@ -21,6 +21,7 @@ */ package com.nexmo.client.account; +import com.nexmo.client.AbstractClient; import com.nexmo.client.HttpWrapper; import com.nexmo.client.NexmoClient; import com.nexmo.client.NexmoClientException; @@ -31,8 +32,10 @@ * A client for talking to the Nexmo Number Insight API. The standard way to obtain an instance of this class is to use * {@link NexmoClient#getInsightClient()}. */ -public class AccountClient { +public class AccountClient extends AbstractClient { protected BalanceEndpoint balance; + protected PricingEndpoint pricing; + protected PrefixPricingEndpoint prefixPricing; /** * Constructor. @@ -40,10 +43,64 @@ public class AccountClient { * @param httpWrapper (required) shared HTTP wrapper object used for making REST calls. */ public AccountClient(HttpWrapper httpWrapper) { + super(httpWrapper); + this.balance = new BalanceEndpoint(httpWrapper); + this.pricing = new PricingEndpoint(httpWrapper); + this.prefixPricing = new PrefixPricingEndpoint(httpWrapper); } public BalanceResponse getBalance() throws IOException, NexmoClientException { return this.balance.execute(); } + + /** + * Retrieve the voice pricing for a specified country. + * + * @param country The two-character country code for which you would like to retrieve pricing. + * @return PricingResponse object which contains the results from the API. + * @throws IOException if a network error occurred contacting the Nexmo Account API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public PricingResponse getVoicePrice(String country) throws IOException, NexmoClientException { + return getVoicePrice(new PricingRequest(country)); + } + + private PricingResponse getVoicePrice(PricingRequest pricingRequest) throws IOException, NexmoClientException { + return this.pricing.getPrice(ServiceType.VOICE, pricingRequest); + } + + /** + * Retrieve the SMS pricing for a specified country. + * + * @param country The two-character country code for which you would like to retrieve pricing. + * @return PricingResponse object which contains the results from the API. + * @throws IOException if a network error occurred contacting the Nexmo Account API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public PricingResponse getSmsPrice(String country) throws IOException, NexmoClientException { + return getSmsPrice(new PricingRequest(country)); + } + + private PricingResponse getSmsPrice(PricingRequest pricingRequest) throws IOException, NexmoClientException { + return this.pricing.getPrice(ServiceType.SMS, pricingRequest); + } + + /** + * Retrieve the pricing for a specified prefix. + * + * @param type The type of service to retrieve pricing for. + * @param prefix The prefix to retrieve the pricing for. + * @return PricingResponse object which contains the results from the API. + * @throws IOException if a network error occurred contacting the Nexmo Account API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public PrefixPricingResponse getPrefixPrice(ServiceType type, + String prefix) throws IOException, NexmoClientException { + return getPrefixPrice(new PrefixPricingRequest(type, prefix)); + } + + private PrefixPricingResponse getPrefixPrice(PrefixPricingRequest prefixPricingRequest) throws IOException, NexmoClientException { + return this.prefixPricing.getPrice(prefixPricingRequest); + } } diff --git a/src/main/java/com/nexmo/client/account/PrefixPricingEndpoint.java b/src/main/java/com/nexmo/client/account/PrefixPricingEndpoint.java new file mode 100644 index 000000000..1d194a7e2 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PrefixPricingEndpoint.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; + +public class PrefixPricingEndpoint { + private PrefixPricingMethod prefixPricingMethod; + + PrefixPricingEndpoint(HttpWrapper httpWrapper) { + this.prefixPricingMethod = new PrefixPricingMethod(httpWrapper); + } + + PrefixPricingResponse getPrice(PrefixPricingRequest prefixPricingRequest) throws IOException, NexmoClientException { + return this.prefixPricingMethod.execute(prefixPricingRequest); + } +} diff --git a/src/main/java/com/nexmo/client/account/PrefixPricingMethod.java b/src/main/java/com/nexmo/client/account/PrefixPricingMethod.java new file mode 100644 index 000000000..3152d87fb --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PrefixPricingMethod.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.voice.endpoints.AbstractMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; + +import java.io.IOException; + +public class PrefixPricingMethod extends AbstractMethod { + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_BASE_URI = "https://rest.nexmo.com/account/get-prefix-pricing/outbound/"; + + private String baseUri = DEFAULT_BASE_URI; + + PrefixPricingMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(PrefixPricingRequest prefixPricingRequest) { + String uri = this.baseUri + prefixPricingRequest.getServiceType().name().toLowerCase(); + return RequestBuilder.get(uri).addParameter("prefix", prefixPricingRequest.getPrefix()); + } + + @Override + public PrefixPricingResponse parseResponse(HttpResponse response) throws IOException { + return PrefixPricingResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/account/PrefixPricingRequest.java b/src/main/java/com/nexmo/client/account/PrefixPricingRequest.java new file mode 100644 index 000000000..31d071776 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PrefixPricingRequest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +public class PrefixPricingRequest { + private ServiceType serviceType; + private String prefix; + + public PrefixPricingRequest(ServiceType serviceType, String prefix) { + if (serviceType == null) { + throw new IllegalArgumentException("Service type cannot be null."); + } + this.serviceType = serviceType; + this.prefix = prefix; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public String getPrefix() { + return prefix; + } +} diff --git a/src/main/java/com/nexmo/client/account/PrefixPricingResponse.java b/src/main/java/com/nexmo/client/account/PrefixPricingResponse.java new file mode 100644 index 000000000..5b49afa7b --- /dev/null +++ b/src/main/java/com/nexmo/client/account/PrefixPricingResponse.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class PrefixPricingResponse { + private int count; + private List countries; + + public int getCount() { + return count; + } + + public List getCountries() { + return countries; + } + + public static PrefixPricingResponse fromJson(String json) { + try { + return new ObjectMapper().readValue(json, PrefixPricingResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce PrefixPricingResponse from json.", jpe); + } + } +} diff --git a/src/test/java/com/nexmo/client/account/AccountClientTest.java b/src/test/java/com/nexmo/client/account/AccountClientTest.java index 5ad0aa2b4..c265d4124 100644 --- a/src/test/java/com/nexmo/client/account/AccountClientTest.java +++ b/src/test/java/com/nexmo/client/account/AccountClientTest.java @@ -21,19 +21,24 @@ */ package com.nexmo.client.account; +import com.nexmo.client.ClientTest; +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.auth.TokenAuthMethod; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; +import java.math.BigDecimal; + import static org.mockito.Mockito.*; -public class AccountClientTest { - private AccountClient client; +public class AccountClientTest extends ClientTest { private BalanceResponse sentinel; @Before public void setUp() throws Exception { - client = new AccountClient(null); + wrapper = new HttpWrapper(new TokenAuthMethod("not-an-api-key", "secret")); + client = new AccountClient(wrapper); client.balance = mock(BalanceEndpoint.class); sentinel = new BalanceResponse(1.1, true); when(client.balance.execute()).thenReturn(sentinel); @@ -46,4 +51,145 @@ public void testGetBalance() throws Exception { Assert.assertEquals(sentinel, response); } + @Test + public void testGetSmsPrice() throws Exception { + String json = "{\n" + " \"dialingPrefix\": \"1\",\n" + " \"defaultPrice\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"United States of America\",\n" + " \"countryCode\": \"US\",\n" + " \"countryName\": \"United States\",\n" + " \"networks\": [\n" + " {\n" + " \"type\": \"mobile\",\n" + " \"price\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"mcc\": \"987\",\n" + " \"mnc\": \"123\",\n" + " \"networkCode\": \"123456\",\n" + " \"networkName\": \"Test Mobile\"\n" + " },\n" + " {\n" + " \"type\": \"landline\",\n" + " \"price\": \"0.00330000\",\n" + " \"currency\": \"EUR\",\n" + " \"mcc\": \"123\",\n" + " \"mnc\": \"456\",\n" + " \"networkCode\": \"networkcode\",\n" + " \"networkName\": \"Test Landline\"\n" + " } \n" + " ]\n" + "}\n"; + wrapper.setHttpClient(this.stubHttpClient(200, json)); + PricingResponse response = client.getSmsPrice("US"); + Assert.assertEquals("1", response.getDialingPrefix()); + Assert.assertEquals(new BigDecimal("0.00570000"), response.getDefaultPrice()); + Assert.assertEquals("EUR", response.getCurrency()); + Assert.assertEquals("United States of America", response.getCountry().getDisplayName()); + Assert.assertEquals("US", response.getCountry().getCode()); + Assert.assertEquals("United States", response.getCountry().getName()); + + Assert.assertEquals(2, response.getNetworks().size()); + Network first = response.getNetworks().get(0); + Assert.assertEquals(Network.Type.MOBILE, first.getType()); + Assert.assertEquals(new BigDecimal("0.00570000"), first.getPrice()); + Assert.assertEquals("EUR", first.getCurrency()); + Assert.assertEquals("987", first.getMcc()); + Assert.assertEquals("123", first.getMnc()); + Assert.assertEquals("123456", first.getCode()); + Assert.assertEquals("Test Mobile", first.getName()); + + + Network second = response.getNetworks().get(1); + Assert.assertEquals(Network.Type.LANDLINE, second.getType()); + Assert.assertEquals(new BigDecimal("0.00330000"), second.getPrice()); + Assert.assertEquals("EUR", second.getCurrency()); + Assert.assertEquals("123", second.getMcc()); + Assert.assertEquals("456", second.getMnc()); + Assert.assertEquals("networkcode", second.getCode()); + Assert.assertEquals("Test Landline", second.getName()); + } + + @Test + public void testGetVoicePrice() throws Exception { + String json = "{\n" + " \"dialingPrefix\": \"1\",\n" + " \"defaultPrice\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"United States of America\",\n" + " \"countryCode\": \"US\",\n" + " \"countryName\": \"United States\",\n" + " \"networks\": [\n" + " {\n" + " \"type\": \"mobile\",\n" + " \"price\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"mcc\": \"987\",\n" + " \"mnc\": \"123\",\n" + " \"networkCode\": \"123456\",\n" + " \"networkName\": \"Test Mobile\"\n" + " },\n" + " {\n" + " \"type\": \"landline\",\n" + " \"price\": \"0.00330000\",\n" + " \"currency\": \"EUR\",\n" + " \"mcc\": \"123\",\n" + " \"mnc\": \"456\",\n" + " \"networkCode\": \"networkcode\",\n" + " \"networkName\": \"Test Landline\"\n" + " } \n" + " ]\n" + "}\n"; + wrapper.setHttpClient(this.stubHttpClient(200, json)); + PricingResponse response = client.getVoicePrice("US"); + Assert.assertEquals("1", response.getDialingPrefix()); + Assert.assertEquals(new BigDecimal("0.00570000"), response.getDefaultPrice()); + Assert.assertEquals("EUR", response.getCurrency()); + Assert.assertEquals("United States of America", response.getCountry().getDisplayName()); + Assert.assertEquals("US", response.getCountry().getCode()); + Assert.assertEquals("United States", response.getCountry().getName()); + + Assert.assertEquals(2, response.getNetworks().size()); + Network first = response.getNetworks().get(0); + Assert.assertEquals(Network.Type.MOBILE, first.getType()); + Assert.assertEquals(new BigDecimal("0.00570000"), first.getPrice()); + Assert.assertEquals("EUR", first.getCurrency()); + Assert.assertEquals("987", first.getMcc()); + Assert.assertEquals("123", first.getMnc()); + Assert.assertEquals("123456", first.getCode()); + Assert.assertEquals("Test Mobile", first.getName()); + + + Network second = response.getNetworks().get(1); + Assert.assertEquals(Network.Type.LANDLINE, second.getType()); + Assert.assertEquals(new BigDecimal("0.00330000"), second.getPrice()); + Assert.assertEquals("EUR", second.getCurrency()); + Assert.assertEquals("123", second.getMcc()); + Assert.assertEquals("456", second.getMnc()); + Assert.assertEquals("networkcode", second.getCode()); + Assert.assertEquals("Test Landline", second.getName()); + } + + @Test + public void testGetPrefixVoicePrice() throws Exception { + String json = "{\n" + " \"count\": 2,\n" + " \"countries\": [\n" + " {\n" + " \"dialingPrefix\": \"1\",\n" + " \"defaultPrice\": \"0.01270000\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"Canada\",\n" + " \"countryCode\": \"CA\",\n" + " \"countryName\": \"Canada\",\n" + " \"networks\": [\n" + " {\n" + " \"type\": \"mobile\",\n" + " \"price\": \"0.01280000\",\n" + " \"currency\": \"EUR\",\n" + " \"aliases\": [\n" + " \"302998\"\n" + " ],\n" + " \"mcc\": \"302\",\n" + " \"mnc\": \"702\",\n" + " \"networkCode\": \"302702\",\n" + " \"networkName\": \"BELL ALIANT REGIONAL Communications LP\"\n" + " },\n" + " {\n" + " \"type\": \"landline\",\n" + " \"price\": \"0.01000000\",\n" + " \"currency\": \"EUR\",\n" + " \"networkCode\": \"CA-FIXED\",\n" + " \"networkName\": \"Canada Landline\"\n" + " }\n" + " ]\n" + " },\n" + " {\n" + " \"dialingPrefix\": \"1\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"United States Minor Outlying Islands\",\n" + " \"countryCode\": \"UM\",\n" + " \"countryName\": \"United States Minor Outlying Islands\"\n" + " }\n" + " ]\n" + "}"; + wrapper.setHttpClient(this.stubHttpClient(200, json)); + PrefixPricingResponse response = client.getPrefixPrice(ServiceType.VOICE, "1"); + Assert.assertEquals(2, response.getCount()); + Assert.assertEquals(2, response.getCountries().size()); + + PricingResponse firstResponse = response.getCountries().get(0); + Assert.assertEquals("1", firstResponse.getDialingPrefix()); + Assert.assertEquals(new BigDecimal("0.01270000"), firstResponse.getDefaultPrice()); + Assert.assertEquals("EUR", firstResponse.getCurrency()); + Assert.assertEquals("Canada", firstResponse.getCountry().getDisplayName()); + Assert.assertEquals("CA", firstResponse.getCountry().getCode()); + Assert.assertEquals("Canada", firstResponse.getCountry().getName()); + + Assert.assertEquals(2, firstResponse.getNetworks().size()); + Network firstResponseFirstNetwork = firstResponse.getNetworks().get(0); + Assert.assertEquals(Network.Type.MOBILE, firstResponseFirstNetwork.getType()); + Assert.assertEquals(new BigDecimal("0.01280000"), firstResponseFirstNetwork.getPrice()); + Assert.assertEquals("EUR", firstResponseFirstNetwork.getCurrency()); + Assert.assertEquals("302", firstResponseFirstNetwork.getMcc()); + Assert.assertEquals("702", firstResponseFirstNetwork.getMnc()); + Assert.assertEquals("302702", firstResponseFirstNetwork.getCode()); + Assert.assertEquals("BELL ALIANT REGIONAL Communications LP", firstResponseFirstNetwork.getName()); + + + Network firstResponseSecondNetwork = firstResponse.getNetworks().get(1); + Assert.assertEquals(Network.Type.LANDLINE, firstResponseSecondNetwork.getType()); + Assert.assertEquals(new BigDecimal("0.01000000"), firstResponseSecondNetwork.getPrice()); + Assert.assertEquals("EUR", firstResponseSecondNetwork.getCurrency()); + Assert.assertEquals("CA-FIXED", firstResponseSecondNetwork.getCode()); + Assert.assertEquals("Canada Landline", firstResponseSecondNetwork.getName()); + + PricingResponse secondResponse = response.getCountries().get(1); + Assert.assertEquals("1", secondResponse.getDialingPrefix()); + Assert.assertEquals("EUR", secondResponse.getCurrency()); + Assert.assertEquals("United States Minor Outlying Islands", secondResponse.getCountry().getDisplayName()); + Assert.assertEquals("UM", secondResponse.getCountry().getCode()); + Assert.assertEquals("United States Minor Outlying Islands", secondResponse.getCountry().getName()); + } + + @Test + public void testGetPrefixSmsPrice() throws Exception { + String json = "{\n" + " \"count\": 2,\n" + " \"countries\": [\n" + " {\n" + " \"dialingPrefix\": \"1\",\n" + " \"defaultPrice\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"Canada\",\n" + " \"countryCode\": \"CA\",\n" + " \"countryName\": \"Canada\",\n" + " \"networks\": [\n" + " {\n" + " \"type\": \"mobile\",\n" + " \"price\": \"0.00570000\",\n" + " \"currency\": \"EUR\",\n" + " \"aliases\": [\n" + " \"302660\"\n" + " ],\n" + " \"mcc\": \"302\",\n" + " \"mnc\": \"655\",\n" + " \"networkCode\": \"302655\",\n" + " \"networkName\": \"MTS Communications Inc.\"\n" + " }\n" + " ]\n" + " },\n" + " {\n" + " \"dialingPrefix\": \"1\",\n" + " \"currency\": \"EUR\",\n" + " \"countryDisplayName\": \"United States Minor Outlying Islands\",\n" + " \"countryCode\": \"UM\",\n" + " \"countryName\": \"United States Minor Outlying Islands\"\n" + " }\n" + " ]\n" + "}"; + wrapper.setHttpClient(this.stubHttpClient(200, json)); + PrefixPricingResponse response = client.getPrefixPrice(ServiceType.SMS, "1"); + Assert.assertEquals(2, response.getCount()); + Assert.assertEquals(2, response.getCountries().size()); + + PricingResponse firstResponse = response.getCountries().get(0); + Assert.assertEquals("1", firstResponse.getDialingPrefix()); + Assert.assertEquals(new BigDecimal("0.00570000"), firstResponse.getDefaultPrice()); + Assert.assertEquals("EUR", firstResponse.getCurrency()); + Assert.assertEquals("Canada", firstResponse.getCountry().getDisplayName()); + Assert.assertEquals("CA", firstResponse.getCountry().getCode()); + Assert.assertEquals("Canada", firstResponse.getCountry().getName()); + + Assert.assertEquals(1, firstResponse.getNetworks().size()); + Network network = firstResponse.getNetworks().get(0); + Assert.assertEquals(Network.Type.MOBILE, network.getType()); + Assert.assertEquals(new BigDecimal("0.00570000"), network.getPrice()); + Assert.assertEquals("EUR", network.getCurrency()); + Assert.assertEquals("302", network.getMcc()); + Assert.assertEquals("655", network.getMnc()); + Assert.assertEquals("302655", network.getCode()); + Assert.assertEquals("MTS Communications Inc.", network.getName()); + + PricingResponse secondResponse = response.getCountries().get(1); + Assert.assertEquals("1", secondResponse.getDialingPrefix()); + Assert.assertEquals("EUR", secondResponse.getCurrency()); + Assert.assertEquals("United States Minor Outlying Islands", secondResponse.getCountry().getDisplayName()); + Assert.assertEquals("UM", secondResponse.getCountry().getCode()); + Assert.assertEquals("United States Minor Outlying Islands", secondResponse.getCountry().getName()); + } } From 6eadfb71f13bb91689632a5b1b26a4cfb57dd9d8 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 13 Jun 2018 13:27:54 -0400 Subject: [PATCH 06/21] Update README and CHANGELOG to reflect pricing endpoint updates. --- CHANGELOG.md | 4 ++++ README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d50659ccf..4426ab749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Development] +### Added +- Added `getSmsPrice` to `AccountClient` for getting SMS pricing for a country. +- Added `getVoicePrice` to `AccountClient` for getting voice pricing for a country. +- Added `getPrefixPrice` to `AccountClient` for getting SMS and voice pricing for a prefix. ## [3.5.0] - 2018-05-29 ### Changed diff --git a/README.md b/README.md index 959c6a082..ccb261759 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,50 @@ When the user enters the code they received, you can check it like this: client.getVerifyClient().check(ongoingVerify.getRequestId(), CODE) ``` +### Get a List of SMS Prices for a Country + +Get a list of SMS prices for a country with: + +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +PricingResponse response = client.getAccountClient().getSmsPrice("GB"); +System.out.println(response.getDefaultPrice()); +``` + +### Get a List of Voice Prices for a Country + +Get a list of voice prices for a country with: + +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +PricingResponse response = client.getAccountClient().getVoicePrice("US"); +System.out.println(response.getDefaultPrice()); +``` + +### Get a List of SMS Prices for a Prefix + +Get a list of SMS prices for a country with: + +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +PricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.SMS, "1"); +System.out.println(response.getDefaultPrice()); +``` + +### Get a List of Voice Prices for a Prefix + +Get a list of voice prices for a country with: + +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +PricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.VOICE, "1"); +System.out.println(response.getDefaultPrice()); +``` + ### Custom HTTP Configuration If you need to configure the Apache HttpClient used for making requests, you can From 5b59ef3a0433647e4d48cc996fef739b189542a9 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 13 Jun 2018 13:47:06 -0400 Subject: [PATCH 07/21] Update JavaDoc to reflect new return type. --- src/main/java/com/nexmo/client/account/AccountClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/nexmo/client/account/AccountClient.java b/src/main/java/com/nexmo/client/account/AccountClient.java index 72bd3d2a8..88613fd04 100644 --- a/src/main/java/com/nexmo/client/account/AccountClient.java +++ b/src/main/java/com/nexmo/client/account/AccountClient.java @@ -91,7 +91,7 @@ private PricingResponse getSmsPrice(PricingRequest pricingRequest) throws IOExce * * @param type The type of service to retrieve pricing for. * @param prefix The prefix to retrieve the pricing for. - * @return PricingResponse object which contains the results from the API. + * @return PrefixPricingResponse object which contains the results from the API. * @throws IOException if a network error occurred contacting the Nexmo Account API. * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. */ From 68c6a1ce7e0f039d9e2e98d83caeb87afc34e0cd Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 13 Jun 2018 15:17:32 -0400 Subject: [PATCH 08/21] Add the ability to top up accounts. --- CHANGELOG.md | 1 + README.md | 9 +++ .../nexmo/client/account/AccountClient.java | 19 ++++++ .../nexmo/client/account/TopUpEndpoint.java | 39 +++++++++++ .../com/nexmo/client/account/TopUpMethod.java | 64 +++++++++++++++++++ .../nexmo/client/account/TopUpRequest.java | 34 ++++++++++ .../client/account/AccountClientTest.java | 21 ++++++ 7 files changed, 187 insertions(+) create mode 100644 src/main/java/com/nexmo/client/account/TopUpEndpoint.java create mode 100644 src/main/java/com/nexmo/client/account/TopUpMethod.java create mode 100644 src/main/java/com/nexmo/client/account/TopUpRequest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4426ab749..e1810f4b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `getSmsPrice` to `AccountClient` for getting SMS pricing for a country. - Added `getVoicePrice` to `AccountClient` for getting voice pricing for a country. - Added `getPrefixPrice` to `AccountClient` for getting SMS and voice pricing for a prefix. +- Added `topUp` to `AccountClient` for topping up your account which has auto-reload enabled. ## [3.5.0] - 2018-05-29 ### Changed diff --git a/README.md b/README.md index ccb261759..83a595a96 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,15 @@ PricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType. System.out.println(response.getDefaultPrice()); ``` +### Top-up Account + +Top-up your account that has auto-reload enabled with: +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +Boolean successful = client.getAccountClient().topUp("TRANSACTION_NUMBER"); +System.out.println("Success: " + successful); +``` ### Custom HTTP Configuration If you need to configure the Apache HttpClient used for making requests, you can diff --git a/src/main/java/com/nexmo/client/account/AccountClient.java b/src/main/java/com/nexmo/client/account/AccountClient.java index 88613fd04..572bfa799 100644 --- a/src/main/java/com/nexmo/client/account/AccountClient.java +++ b/src/main/java/com/nexmo/client/account/AccountClient.java @@ -36,6 +36,7 @@ public class AccountClient extends AbstractClient { protected BalanceEndpoint balance; protected PricingEndpoint pricing; protected PrefixPricingEndpoint prefixPricing; + protected TopUpEndpoint topUp; /** * Constructor. @@ -48,6 +49,7 @@ public AccountClient(HttpWrapper httpWrapper) { this.balance = new BalanceEndpoint(httpWrapper); this.pricing = new PricingEndpoint(httpWrapper); this.prefixPricing = new PrefixPricingEndpoint(httpWrapper); + this.topUp = new TopUpEndpoint(httpWrapper); } public BalanceResponse getBalance() throws IOException, NexmoClientException { @@ -103,4 +105,21 @@ public PrefixPricingResponse getPrefixPrice(ServiceType type, private PrefixPricingResponse getPrefixPrice(PrefixPricingRequest prefixPricingRequest) throws IOException, NexmoClientException { return this.prefixPricing.getPrice(prefixPricingRequest); } + + /** + * Top-up your account when you have enabled auto-reload in the dashboard. Amount added is based on your initial + * reload-enabled payment. + * + * @param transaction The ID associated with your original auto-reload transaction + * @return Boolean true if successful. + * @throws IOException if a network error occurred contacting the Nexmo Account API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response object. + */ + public Boolean topUp(String transaction) throws IOException, NexmoClientException { + return topUp(new TopUpRequest(transaction)); + } + + private Boolean topUp(TopUpRequest request) throws IOException, NexmoClientException { + return this.topUp.topUp(request); + } } diff --git a/src/main/java/com/nexmo/client/account/TopUpEndpoint.java b/src/main/java/com/nexmo/client/account/TopUpEndpoint.java new file mode 100644 index 000000000..a51b69d4a --- /dev/null +++ b/src/main/java/com/nexmo/client/account/TopUpEndpoint.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; + +public class TopUpEndpoint { + private TopUpMethod topUpMethod; + + TopUpEndpoint(HttpWrapper httpWrapper) { + this.topUpMethod = new TopUpMethod(httpWrapper); + } + + Boolean topUp(TopUpRequest request) throws IOException, NexmoClientException { + return this.topUpMethod.execute(request); + } +} diff --git a/src/main/java/com/nexmo/client/account/TopUpMethod.java b/src/main/java/com/nexmo/client/account/TopUpMethod.java new file mode 100644 index 000000000..57507d4f5 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/TopUpMethod.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.voice.endpoints.AbstractMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class TopUpMethod extends AbstractMethod { + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/account/top-up"; + + private String uri = DEFAULT_URI; + + public TopUpMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(TopUpRequest request) throws NexmoClientException, UnsupportedEncodingException { + return RequestBuilder.get(this.uri).addParameter("trx", request.getTrx()); + } + + @Override + public Boolean parseResponse(HttpResponse response) throws IOException, NexmoClientException { + if (response.getStatusLine().getStatusCode() != 200) { + throw new NexmoBadRequestException(EntityUtils.toString(response.getEntity())); + } + return true; + } +} diff --git a/src/main/java/com/nexmo/client/account/TopUpRequest.java b/src/main/java/com/nexmo/client/account/TopUpRequest.java new file mode 100644 index 000000000..0a27e045e --- /dev/null +++ b/src/main/java/com/nexmo/client/account/TopUpRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.account; + +public class TopUpRequest { + private String trx; + + public TopUpRequest(String trx) { + this.trx = trx; + } + + public String getTrx() { + return trx; + } +} diff --git a/src/test/java/com/nexmo/client/account/AccountClientTest.java b/src/test/java/com/nexmo/client/account/AccountClientTest.java index c265d4124..9ba84b8aa 100644 --- a/src/test/java/com/nexmo/client/account/AccountClientTest.java +++ b/src/test/java/com/nexmo/client/account/AccountClientTest.java @@ -23,6 +23,7 @@ import com.nexmo.client.ClientTest; import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; import com.nexmo.client.auth.TokenAuthMethod; import junit.framework.Assert; import org.junit.Before; @@ -192,4 +193,24 @@ public void testGetPrefixSmsPrice() throws Exception { Assert.assertEquals("UM", secondResponse.getCountry().getCode()); Assert.assertEquals("United States Minor Outlying Islands", secondResponse.getCountry().getName()); } + + @Test + public void testTopUpSuccessful() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(200, "")); + Assert.assertTrue(client.topUp("ABC123")); + } + + @Test(expected = NexmoClientException.class) + public void testTopUpFailedAuth() throws Exception { + String json = "{\"error-code\":\"401\",\"error-code-label\":\"authentication failed\"}"; + wrapper.setHttpClient(this.stubHttpClient(401, json)); + client.topUp("ABC123"); + } + + @Test(expected = NexmoClientException.class) + public void testTopUpFailed() throws Exception { + String json = "{\"error-code\":\"420\",\"error-code-label\":\"topup failed\"}"; + wrapper.setHttpClient(this.stubHttpClient(401, json)); + client.topUp("ABC123"); + } } From 5e8882578fcf067729761a6f2d1ff5dbe3d52951 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 13 Jun 2018 15:21:38 -0400 Subject: [PATCH 09/21] Clean-up README for other pricing endpoints. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 83a595a96..c2ec3a212 100644 --- a/README.md +++ b/README.md @@ -218,8 +218,8 @@ Get a list of SMS prices for a country with: ```java AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); NexmoClient client = new NexmoClient(auth); -PricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.SMS, "1"); -System.out.println(response.getDefaultPrice()); +PrefixPricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.SMS, "1"); +System.out.println(response.getCountries().get(0).getDefaultPrice()); ``` ### Get a List of Voice Prices for a Prefix @@ -229,8 +229,8 @@ Get a list of voice prices for a country with: ```java AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); NexmoClient client = new NexmoClient(auth); -PricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.VOICE, "1"); -System.out.println(response.getDefaultPrice()); +PrefixPricingResponse response = client.getAccountClient().getPrefixPrice(ServiceType.VOICE, "1"); +System.out.println(response.getCountries().get(0).getDefaultPrice()); ``` ### Top-up Account From 447ae876a9c5661c4e656a06fbeb9ec15513b460 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Thu, 14 Jun 2018 15:01:29 -0400 Subject: [PATCH 10/21] Top-up switched from Boolean to void return as it will always return true or throw an exception. --- README.md | 3 +-- .../java/com/nexmo/client/account/AccountClient.java | 12 ++++++------ .../java/com/nexmo/client/account/TopUpEndpoint.java | 4 ++-- .../java/com/nexmo/client/account/TopUpMethod.java | 7 ++++--- .../com/nexmo/client/account/AccountClientTest.java | 3 ++- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c2ec3a212..cadff32d5 100644 --- a/README.md +++ b/README.md @@ -239,8 +239,7 @@ Top-up your account that has auto-reload enabled with: ```java AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); NexmoClient client = new NexmoClient(auth); -Boolean successful = client.getAccountClient().topUp("TRANSACTION_NUMBER"); -System.out.println("Success: " + successful); +client.getAccountClient().topUp("TRANSACTION_NUMBER"); ``` ### Custom HTTP Configuration diff --git a/src/main/java/com/nexmo/client/account/AccountClient.java b/src/main/java/com/nexmo/client/account/AccountClient.java index 572bfa799..56cb0619f 100644 --- a/src/main/java/com/nexmo/client/account/AccountClient.java +++ b/src/main/java/com/nexmo/client/account/AccountClient.java @@ -111,15 +111,15 @@ private PrefixPricingResponse getPrefixPrice(PrefixPricingRequest prefixPricingR * reload-enabled payment. * * @param transaction The ID associated with your original auto-reload transaction - * @return Boolean true if successful. * @throws IOException if a network error occurred contacting the Nexmo Account API. - * @throws NexmoClientException if there was a problem with the Nexmo request or response object. + * @throws NexmoClientException if there was a problem with the Nexmo request or response object indicating that + * the request was unsuccessful. */ - public Boolean topUp(String transaction) throws IOException, NexmoClientException { - return topUp(new TopUpRequest(transaction)); + public void topUp(String transaction) throws IOException, NexmoClientException { + topUp(new TopUpRequest(transaction)); } - private Boolean topUp(TopUpRequest request) throws IOException, NexmoClientException { - return this.topUp.topUp(request); + private void topUp(TopUpRequest request) throws IOException, NexmoClientException { + this.topUp.topUp(request); } } diff --git a/src/main/java/com/nexmo/client/account/TopUpEndpoint.java b/src/main/java/com/nexmo/client/account/TopUpEndpoint.java index a51b69d4a..c1ea6da18 100644 --- a/src/main/java/com/nexmo/client/account/TopUpEndpoint.java +++ b/src/main/java/com/nexmo/client/account/TopUpEndpoint.java @@ -33,7 +33,7 @@ public class TopUpEndpoint { this.topUpMethod = new TopUpMethod(httpWrapper); } - Boolean topUp(TopUpRequest request) throws IOException, NexmoClientException { - return this.topUpMethod.execute(request); + void topUp(TopUpRequest request) throws IOException, NexmoClientException { + this.topUpMethod.execute(request); } } diff --git a/src/main/java/com/nexmo/client/account/TopUpMethod.java b/src/main/java/com/nexmo/client/account/TopUpMethod.java index 57507d4f5..d1002c6c9 100644 --- a/src/main/java/com/nexmo/client/account/TopUpMethod.java +++ b/src/main/java/com/nexmo/client/account/TopUpMethod.java @@ -33,7 +33,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; -public class TopUpMethod extends AbstractMethod { +public class TopUpMethod extends AbstractMethod { private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; private static final String DEFAULT_URI = "https://rest.nexmo.com/account/top-up"; @@ -55,10 +55,11 @@ public RequestBuilder makeRequest(TopUpRequest request) throws NexmoClientExcept } @Override - public Boolean parseResponse(HttpResponse response) throws IOException, NexmoClientException { + public Void parseResponse(HttpResponse response) throws IOException, NexmoClientException { if (response.getStatusLine().getStatusCode() != 200) { throw new NexmoBadRequestException(EntityUtils.toString(response.getEntity())); } - return true; + + return null; } } diff --git a/src/test/java/com/nexmo/client/account/AccountClientTest.java b/src/test/java/com/nexmo/client/account/AccountClientTest.java index 9ba84b8aa..479ba8728 100644 --- a/src/test/java/com/nexmo/client/account/AccountClientTest.java +++ b/src/test/java/com/nexmo/client/account/AccountClientTest.java @@ -197,7 +197,8 @@ public void testGetPrefixSmsPrice() throws Exception { @Test public void testTopUpSuccessful() throws Exception { wrapper.setHttpClient(this.stubHttpClient(200, "")); - Assert.assertTrue(client.topUp("ABC123")); + // No assertions as an exception will be thrown if failure occurs. + client.topUp("ABC123"); } @Test(expected = NexmoClientException.class) From f3308e43472889f5d5e755e57c2be5215a607c79 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Thu, 14 Jun 2018 15:07:39 -0400 Subject: [PATCH 11/21] Update Codacy Badge to new location. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cadff32d5..2cc1fc079 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Maven Release](https://maven-badges.herokuapp.com/maven-central/com.nexmo/client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.nexmo/client) [![Build Status](https://travis-ci.org/Nexmo/nexmo-java.svg?branch=version-2)](https://travis-ci.org/Nexmo/nexmo-java) [![codecov](https://codecov.io/gh/Nexmo/nexmo-java/branch/version-2/graph/badge.svg)](https://codecov.io/gh/Nexmo/nexmo-java) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/9888a9f2ec0d4599a11762e5d946da17)](https://www.codacy.com/app/mark-smith/nexmo-java?utm_source=github.com&utm_medium=referral&utm_content=Nexmo/nexmo-java&utm_campaign=Badge_Grade) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0049e762c00b4ce999f45492795ba50a)](https://www.codacy.com/app/cr0wst/nexmo-java?utm_source=github.com&utm_medium=referral&utm_content=Nexmo/nexmo-java&utm_campaign=Badge_Grade) You can use this Java client library to add [Nexmo's API](#api-coverage) to your application. To use this, you'll From dc3bbc4a1a91e5b708d23a98833271a305eedf05 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Mon, 18 Jun 2018 12:05:07 -0400 Subject: [PATCH 12/21] Remove deprecation from VerifyResult as VerifyResponse is not ready for external usage. --- src/main/java/com/nexmo/client/verify/VerifyResult.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/nexmo/client/verify/VerifyResult.java b/src/main/java/com/nexmo/client/verify/VerifyResult.java index e4c65edf4..ddacc56e6 100644 --- a/src/main/java/com/nexmo/client/verify/VerifyResult.java +++ b/src/main/java/com/nexmo/client/verify/VerifyResult.java @@ -21,11 +21,6 @@ */ package com.nexmo.client.verify; - -/** - * @deprecated Relies on XML Endpoint, use {@link VerifyResponse} - */ -@Deprecated public class VerifyResult extends BaseResult { private final String requestId; From f7863e17063ca73d66b522910b18e3c3b561cee0 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Mon, 18 Jun 2018 13:36:24 -0400 Subject: [PATCH 13/21] Add getSms to SmsClient --- CHANGELOG.md | 2 +- .../java/com/nexmo/client/sms/SmsClient.java | 32 ++++++---- .../client/sms/SmsSingleSearchEndpoint.java | 63 +++++++++++++++++++ .../client/sms/SmsSingleSearchResponse.java | 40 ++++++++++++ .../com/nexmo/client/sms/SmsClientTest.java | 37 ++++++++++- 5 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/nexmo/client/sms/SmsSingleSearchEndpoint.java create mode 100644 src/main/java/com/nexmo/client/sms/SmsSingleSearchResponse.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e1810f4b6..cb16dc018 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `getVoicePrice` to `AccountClient` for getting voice pricing for a country. - Added `getPrefixPrice` to `AccountClient` for getting SMS and voice pricing for a prefix. - Added `topUp` to `AccountClient` for topping up your account which has auto-reload enabled. - +- Added `getSms` to `SmsClient` for searching for a single message by id. ## [3.5.0] - 2018-05-29 ### Changed - Updated `VerifyClient` to use the JSON endpoints instead of XML. diff --git a/src/main/java/com/nexmo/client/sms/SmsClient.java b/src/main/java/com/nexmo/client/sms/SmsClient.java index 79a639030..d289a921a 100644 --- a/src/main/java/com/nexmo/client/sms/SmsClient.java +++ b/src/main/java/com/nexmo/client/sms/SmsClient.java @@ -43,6 +43,7 @@ public class SmsClient { private SendMessageEndpoint message; private SmsSearchEndpoint search; private SearchRejectedMessagesEndpoint rejected; + private SmsSingleSearchEndpoint singleSearch; /** * Create a new SmsClient. @@ -51,6 +52,7 @@ public SmsClient(HttpWrapper httpWrapper) { this.message = new SendMessageEndpoint(httpWrapper); this.search = new SmsSearchEndpoint(httpWrapper); this.rejected = new SearchRejectedMessagesEndpoint(httpWrapper); + this.singleSearch = new SmsSingleSearchEndpoint(httpWrapper); } /** @@ -79,8 +81,7 @@ public SmsSubmissionResult[] submitMessage(Message message) throws IOException, * You should probably use the helper methods {@link #searchMessages(String, String...)} or * {@link #searchMessages(String, String...)} instead. */ - public SearchSmsResponse searchMessages(SearchSmsRequest request) - throws IOException, NexmoClientException { + public SearchSmsResponse searchMessages(SearchSmsRequest request) throws IOException, NexmoClientException { return this.search.execute(request); } @@ -91,8 +92,7 @@ public SearchSmsResponse searchMessages(SearchSmsRequest request) * @param ids optional extra IDs to look up * @return SMS data matching the provided criteria */ - public SearchSmsResponse searchMessages(String id, String... ids) - throws IOException, NexmoClientException { + public SearchSmsResponse searchMessages(String id, String... ids) throws IOException, NexmoClientException { List idList = new ArrayList<>(ids.length + 1); idList.add(id); idList.addAll(Arrays.asList(ids)); @@ -106,8 +106,7 @@ public SearchSmsResponse searchMessages(String id, String... ids) * @param to the MSISDN number of the SMS recipient * @return SMS data matching the provided criteria */ - public SearchSmsResponse searchMessages(Date date, String to) - throws IOException, NexmoClientException { + public SearchSmsResponse searchMessages(Date date, String to) throws IOException, NexmoClientException { return this.searchMessages(new SmsDateSearchRequest(date, to)); } @@ -115,11 +114,10 @@ public SearchSmsResponse searchMessages(Date date, String to) * Search for rejected SMS transactions using a {@link SearchRejectedMessagesRequest}. *

* You should probably use {@link #searchRejectedMessages(Date, String)} instead. - + * * @return rejection data matching the provided criteria */ - public SearchRejectedMessagesResponse searchRejectedMessages(SearchRejectedMessagesRequest request) - throws IOException, NexmoClientException { + public SearchRejectedMessagesResponse searchRejectedMessages(SearchRejectedMessagesRequest request) throws IOException, NexmoClientException { return this.rejected.execute(request); } @@ -130,8 +128,20 @@ public SearchRejectedMessagesResponse searchRejectedMessages(SearchRejectedMessa * @param to the MSISDN number of the SMS recipient * @return rejection data matching the provided criteria */ - public SearchRejectedMessagesResponse searchRejectedMessages(Date date, String to) - throws IOException, NexmoClientException { + public SearchRejectedMessagesResponse searchRejectedMessages(Date date, + String to) throws IOException, NexmoClientException { return this.searchRejectedMessages(new SearchRejectedMessagesRequest(date, to)); } + + /** + * Search for a single SMS by id. + * + * @param id The message id to search for. + * @return SmsSingleSearchResponse object containing the details of the SMS. + * @throws NexmoResponseParseException if the HTTP response could not be parsed. + * @throws IOException There has been an error attempting to communicate with the Nexmo service (e.g. Network failure). + */ + public SmsSingleSearchResponse getSms(String id) throws IOException, NexmoClientException { + return this.singleSearch.execute(id); + } } diff --git a/src/main/java/com/nexmo/client/sms/SmsSingleSearchEndpoint.java b/src/main/java/com/nexmo/client/sms/SmsSingleSearchEndpoint.java new file mode 100644 index 000000000..3d4dc969c --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsSingleSearchEndpoint.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011-2017 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.sms; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.voice.endpoints.AbstractMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class SmsSingleSearchEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/search/message"; + + private String uri = DEFAULT_URI; + + public SmsSingleSearchEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(String id) throws NexmoClientException, UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri); + requestBuilder.addParameter("id", id); + return requestBuilder; + } + + @Override + public SmsSingleSearchResponse parseResponse(HttpResponse response) throws IOException { + return SmsSingleSearchResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/sms/SmsSingleSearchResponse.java b/src/main/java/com/nexmo/client/sms/SmsSingleSearchResponse.java new file mode 100644 index 000000000..50cbbfe99 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsSingleSearchResponse.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.sms; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; +import java.text.SimpleDateFormat; + +public class SmsSingleSearchResponse extends SmsDetails { + public static SmsSingleSearchResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + return mapper.readValue(json, SmsSingleSearchResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce SmsSingleSearchResponse from json.", jpe); + } + } +} diff --git a/src/test/java/com/nexmo/client/sms/SmsClientTest.java b/src/test/java/com/nexmo/client/sms/SmsClientTest.java index d7f790309..471f54270 100644 --- a/src/test/java/com/nexmo/client/sms/SmsClientTest.java +++ b/src/test/java/com/nexmo/client/sms/SmsClientTest.java @@ -38,12 +38,11 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -224,4 +223,36 @@ public void testSearchRejected() throws Exception { ); assertThat(response.getCount(), CoreMatchers.equalTo(1)); } + + @Test + public void testSearchSingleMessagesId() throws Exception { + this.wrapper.setHttpClient(this.stubHttpClient(200, "{\n" + + " \"message-id\": \"00A0B0C0\",\n" + + " \"account-id\": \"key\",\n" + + " \"network\": \"20810\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456890\",\n" + + " \"body\": \"hello world\",\n" + + " \"price\": \"0.04500000\",\n" + + " \"date-received\": \"2011-11-25 16:03:00\",\n" + + " \"final-status\": \"DELIVRD\",\n" + + " \"date-closed\": \"2011-11-25 16:03:00\",\n" + + " \"latency\": 11151,\n" + + " \"type\": \"MT\"\n" + + " }")); + + SmsSingleSearchResponse response = client.getSms("an-id"); + assertEquals("00A0B0C0", response.getMessageId()); + assertEquals("key", response.getAccountId()); + assertEquals("20810", response.getNetwork()); + assertEquals("MyApp", response.getFrom()); + assertEquals("123456890", response.getTo()); + assertEquals("hello world", response.getBody()); + assertEquals("0.04500000", response.getPrice()); + assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2011-11-25 16:03:00"), response.getDateReceived()); + assertEquals("DELIVRD", response.getFinalStatus()); + assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2011-11-25 16:03:00"), response.getDateClosed()); + assertEquals(new Integer(11151), response.getLatency()); + assertEquals("MT", response.getType()); + } } From 71647fd6f68b54e28206aeb2d978acd2819bae3f Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 20 Jun 2018 16:16:04 -0400 Subject: [PATCH 14/21] Travis will now use OpenJDK for Java 7 as Maven Central no longer supports TLS1.1. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 727c7ff58..06f977c42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ language: java jdk: - oraclejdk8 - - oraclejdk7 + - openjdk7 after_success: - bash <(curl -s https://codecov.io/bash) From 8e3edb13dff36653c9baece82071e385a4ff4255 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 20 Jun 2018 16:49:22 -0400 Subject: [PATCH 15/21] Instruct Gradle to fallback to http when compiling under Java 7 as the version of JDK 7 that Travis CI uses does not support TLSv1.2 --- .travis.yml | 2 +- build.gradle | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 06f977c42..727c7ff58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ language: java jdk: - oraclejdk8 - - openjdk7 + - oraclejdk7 after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/build.gradle b/build.gradle index 8a619f714..265638026 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import org.gradle.internal.jvm.Jvm + buildscript { repositories { jcenter() @@ -24,7 +26,12 @@ sourceCompatibility = "1.7" targetCompatibility = "1.7" repositories { - mavenCentral() + if (Jvm.current().javaVersion.toString() == "1.7") { + // Fall back to HTTP because the public Oracle and OpenJDK 1.7 versions don't support TLSv1.2 + maven { url "http://repo.maven.apache.org/maven2/" } + } else { + mavenCentral() + } } tasks.withType(JavaCompile) { From bfc1f2c2b5b6c4bb7349a3724679b599871833e6 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Wed, 20 Jun 2018 15:48:15 -0400 Subject: [PATCH 16/21] Add access to the Conversion API. --- CHANGELOG.md | 1 + README.md | 13 +++ .../java/com/nexmo/client/NexmoClient.java | 7 ++ .../client/conversion/ConversionClient.java | 66 +++++++++++++++ .../client/conversion/ConversionEndpoint.java | 39 +++++++++ .../client/conversion/ConversionMethod.java | 77 +++++++++++++++++ .../client/conversion/ConversionRequest.java | 58 +++++++++++++ .../conversion/ConversionClientTest.java | 83 +++++++++++++++++++ .../conversion/ConversionMethodTest.java | 76 +++++++++++++++++ 9 files changed, 420 insertions(+) create mode 100644 src/main/java/com/nexmo/client/conversion/ConversionClient.java create mode 100644 src/main/java/com/nexmo/client/conversion/ConversionEndpoint.java create mode 100644 src/main/java/com/nexmo/client/conversion/ConversionMethod.java create mode 100644 src/main/java/com/nexmo/client/conversion/ConversionRequest.java create mode 100644 src/test/java/com/nexmo/client/conversion/ConversionClientTest.java create mode 100644 src/test/java/com/nexmo/client/conversion/ConversionMethodTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index e1810f4b6..41596a2cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `getVoicePrice` to `AccountClient` for getting voice pricing for a country. - Added `getPrefixPrice` to `AccountClient` for getting SMS and voice pricing for a prefix. - Added `topUp` to `AccountClient` for topping up your account which has auto-reload enabled. +- Added `ConversionClient` and the ability to interact with the Nexmo Conversion API. ## [3.5.0] - 2018-05-29 ### Changed diff --git a/README.md b/README.md index 2cc1fc079..3cbf77e7c 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,19 @@ AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); NexmoClient client = new NexmoClient(auth); client.getAccountClient().topUp("TRANSACTION_NUMBER"); ``` + +### Submit Conversion + +Submit a request to the Conversion API when it has been enabled on your account with: +```java +AuthMethod auth = new TokenAuthMethod(API_KEY, API_SECRET); +NexmoClient client = new NexmoClient(auth); +this.client.submitConversion(ConversionRequest.Type.VOICE, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); +``` + ### Custom HTTP Configuration If you need to configure the Apache HttpClient used for making requests, you can diff --git a/src/main/java/com/nexmo/client/NexmoClient.java b/src/main/java/com/nexmo/client/NexmoClient.java index 7aa27ffff..255ea365f 100644 --- a/src/main/java/com/nexmo/client/NexmoClient.java +++ b/src/main/java/com/nexmo/client/NexmoClient.java @@ -27,6 +27,7 @@ import com.nexmo.client.auth.AuthMethod; import com.nexmo.client.auth.JWTAuthMethod; import com.nexmo.client.auth.NexmoUnacceptableAuthException; +import com.nexmo.client.conversion.ConversionClient; import com.nexmo.client.insight.InsightClient; import com.nexmo.client.numbers.NumbersClient; import com.nexmo.client.sms.SmsClient; @@ -53,6 +54,7 @@ public class NexmoClient { private final VoiceClient voice; private final VerifyClient verify; private final SnsClient sns; + private final ConversionClient conversion; private HttpWrapper httpWrapper; @@ -67,6 +69,7 @@ public NexmoClient(AuthMethod... authMethods) { this.voice = new VoiceClient(this.httpWrapper); this.sms = new SmsClient(this.httpWrapper); this.sns = new SnsClient(this.httpWrapper); + this.conversion = new ConversionClient(this.httpWrapper); } /** @@ -112,6 +115,10 @@ public VoiceClient getVoiceClient() { return this.voice; } + public ConversionClient getConversionClient() { + return this.conversion; + } + /** * Generate a JWT for the application the client has been configured with. * diff --git a/src/main/java/com/nexmo/client/conversion/ConversionClient.java b/src/main/java/com/nexmo/client/conversion/ConversionClient.java new file mode 100644 index 000000000..6e2bf22fb --- /dev/null +++ b/src/main/java/com/nexmo/client/conversion/ConversionClient.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import com.nexmo.client.AbstractClient; +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClient; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; +import java.util.Date; + +/** + * A client for talking to the Nexmo Conversion API. The standard way to obtain an instance of this class is to use + * {@link NexmoClient#getConversionClient()}. + *

+ * Allows you to tell Nexmo about the reliability of your 2FA communications. + *

+ * More information on method parameters can be found at Nexmo website: + * https://developer.nexmo.com/messaging/conversion-api/overview + */ +public class ConversionClient extends AbstractClient { + private ConversionEndpoint conversionEndpoint; + + public ConversionClient(HttpWrapper httpWrapper) { + super(httpWrapper); + + this.conversionEndpoint = new ConversionEndpoint(httpWrapper); + } + + /** + * Submit a request to the Conversion API indicating whether or not a message was delivered. + * + * @param type The {@link ConversionRequest.Type} type of com.nexmo.client.conversion. + * @param messageId The id of the message that was sent. + * @param delivered A boolean indicating whether or not it was delivered. + * @param timestamp A timestamp of when it was known to be delivered. + * @throws IOException if a network error occurred contacting the Nexmo Conversion API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public void submitConversion(ConversionRequest.Type type, + String messageId, + boolean delivered, + Date timestamp) throws IOException, NexmoClientException { + this.conversionEndpoint.submitConversion(new ConversionRequest(type, messageId, delivered, timestamp)); + } +} diff --git a/src/main/java/com/nexmo/client/conversion/ConversionEndpoint.java b/src/main/java/com/nexmo/client/conversion/ConversionEndpoint.java new file mode 100644 index 000000000..dd11d72aa --- /dev/null +++ b/src/main/java/com/nexmo/client/conversion/ConversionEndpoint.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; + +class ConversionEndpoint { + private ConversionMethod conversionMethod; + + ConversionEndpoint(HttpWrapper httpWrapper) { + this.conversionMethod = new ConversionMethod(httpWrapper); + } + + void submitConversion(ConversionRequest request) throws IOException, NexmoClientException { + this.conversionMethod.execute(request); + } +} diff --git a/src/main/java/com/nexmo/client/conversion/ConversionMethod.java b/src/main/java/com/nexmo/client/conversion/ConversionMethod.java new file mode 100644 index 000000000..9774cd04d --- /dev/null +++ b/src/main/java/com/nexmo/client/conversion/ConversionMethod.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.auth.SignatureAuthMethod; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.voice.endpoints.AbstractMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; + +class ConversionMethod extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{SignatureAuthMethod.class, TokenAuthMethod.class}; + + private static final String DEFAULT_BASE_URI = "https://api.nexmo.com/conversions/"; + + private String baseUri = DEFAULT_BASE_URI; + + ConversionMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(ConversionRequest conversionRequest) throws NexmoClientException, UnsupportedEncodingException { + String uri = this.baseUri + conversionRequest.getType().name().toLowerCase(); + return RequestBuilder.post(uri) + .addParameter("message-id", conversionRequest.getMessageId()) + .addParameter("delivered", String.valueOf(conversionRequest.isDelivered())) + .addParameter("timestamp", + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(conversionRequest.getTimestamp())); + } + + @Override + public Void parseResponse(HttpResponse response) throws IOException, NexmoClientException { + if (response.getStatusLine().getStatusCode() != 200) { + throw new NexmoBadRequestException(EntityUtils.toString(response.getEntity())); + } + + return null; + } + + public String getBaseUri() { + return this.baseUri; + } +} diff --git a/src/main/java/com/nexmo/client/conversion/ConversionRequest.java b/src/main/java/com/nexmo/client/conversion/ConversionRequest.java new file mode 100644 index 000000000..2899d09ef --- /dev/null +++ b/src/main/java/com/nexmo/client/conversion/ConversionRequest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import java.util.Date; + +public class ConversionRequest { + private Type type; + private String messageId; + private boolean delivered; + private Date timestamp; + + public ConversionRequest(Type type, String messageId, boolean delivered, Date timestamp) { + this.type = type; + this.messageId = messageId; + this.delivered = delivered; + this.timestamp = timestamp; + } + + public Type getType() { + return type; + } + + public String getMessageId() { + return messageId; + } + + public boolean isDelivered() { + return delivered; + } + + public Date getTimestamp() { + return timestamp; + } + + public enum Type { + SMS, VOICE + } +} diff --git a/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java b/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java new file mode 100644 index 000000000..2076b66c7 --- /dev/null +++ b/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import com.nexmo.client.ClientTest; +import com.nexmo.client.NexmoBadRequestException; +import org.junit.Before; +import org.junit.Test; + +import java.text.SimpleDateFormat; + +public class ConversionClientTest extends ClientTest { + @Before + public void setUp() { + client = new ConversionClient(wrapper); + } + + @Test + public void testSuccessfulResponse() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(200, "")); + this.client.submitConversion(ConversionRequest.Type.VOICE, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } + + @Test(expected = NexmoBadRequestException.class) + public void testWrongCredentials() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(401, "")); + this.client.submitConversion(ConversionRequest.Type.SMS, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } + + @Test(expected = NexmoBadRequestException.class) + public void testConversionNotEnabled() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(402, "")); + this.client.submitConversion(ConversionRequest.Type.SMS, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } + + @Test(expected = NexmoBadRequestException.class) + public void testInvalidParameters() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(423, "")); + this.client.submitConversion(ConversionRequest.Type.SMS, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } + + @Test(expected = NexmoBadRequestException.class) + public void testInvalidParametersEnhanceCalm() throws Exception { + wrapper.setHttpClient(this.stubHttpClient(420, "")); + this.client.submitConversion(ConversionRequest.Type.SMS, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } + + +} diff --git a/src/test/java/com/nexmo/client/conversion/ConversionMethodTest.java b/src/test/java/com/nexmo/client/conversion/ConversionMethodTest.java new file mode 100644 index 000000000..e2b40b688 --- /dev/null +++ b/src/test/java/com/nexmo/client/conversion/ConversionMethodTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011-2018 Nexmo Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.nexmo.client.conversion; + +import org.apache.http.NameValuePair; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ConversionMethodTest { + @Test + public void testConstructParametersWithSms() throws Exception { + ConversionMethod method = new ConversionMethod(null); + ConversionRequest request = new ConversionRequest(ConversionRequest.Type.SMS, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse( + "2014-03-04 10:11:12")); + RequestBuilder requestBuilder = method.makeRequest(request); + List params = requestBuilder.getParameters(); + + assertContainsParam(params, "message-id", "MESSAGE-ID"); + assertContainsParam(params, "delivered", "true"); + assertContainsParam(params, "timestamp", "2014-03-04 10:11:12"); + assertEquals(method.getBaseUri() + ConversionRequest.Type.SMS.name().toLowerCase(), + requestBuilder.getUri().toString()); + } + + @Test + public void testConstructParametersWithVoice() throws Exception { + ConversionMethod method = new ConversionMethod(null); + ConversionRequest request = new ConversionRequest(ConversionRequest.Type.VOICE, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse( + "2014-03-04 10:11:12")); + RequestBuilder requestBuilder = method.makeRequest(request); + List params = requestBuilder.getParameters(); + + assertContainsParam(params, "message-id", "MESSAGE-ID"); + assertContainsParam(params, "delivered", "true"); + assertContainsParam(params, "timestamp", "2014-03-04 10:11:12"); + assertEquals(method.getBaseUri() + ConversionRequest.Type.VOICE.name().toLowerCase(), + requestBuilder.getUri().toString()); + } + + private void assertContainsParam(List params, String key, String value) { + NameValuePair item = new BasicNameValuePair(key, value); + assertTrue("" + params + " should contain " + item, params.contains(item)); + } +} From 0ffda2645c8c989aff87009df599a8395f238e48 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Thu, 21 Jun 2018 10:17:17 -0400 Subject: [PATCH 17/21] Force a failure if an exception is raised. --- .../conversion/ConversionClientTest.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java b/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java index 2076b66c7..b99ccf6ae 100644 --- a/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java +++ b/src/test/java/com/nexmo/client/conversion/ConversionClientTest.java @@ -28,6 +28,8 @@ import java.text.SimpleDateFormat; +import static org.junit.Assert.fail; + public class ConversionClientTest extends ClientTest { @Before public void setUp() { @@ -35,12 +37,16 @@ public void setUp() { } @Test - public void testSuccessfulResponse() throws Exception { - wrapper.setHttpClient(this.stubHttpClient(200, "")); - this.client.submitConversion(ConversionRequest.Type.VOICE, - "MESSAGE-ID", - true, - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + public void testSuccessfulResponse() { + try { + wrapper.setHttpClient(this.stubHttpClient(200, "")); + this.client.submitConversion(ConversionRequest.Type.VOICE, + "MESSAGE-ID", + true, + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-03-04 10:11:12")); + } catch (Exception e) { + fail("No exceptions should be thrown."); + } } @Test(expected = NexmoBadRequestException.class) From 3a3786b386b6173b4b64793a3c7ca78dfb9fc45a Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Tue, 3 Jul 2018 11:11:16 -0400 Subject: [PATCH 18/21] Remove deprecation until a proper workaround has been developed. --- .../com/nexmo/client/verify/CheckResult.java | 4 -- .../com/nexmo/client/verify/SearchResult.java | 60 ++++++++----------- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/nexmo/client/verify/CheckResult.java b/src/main/java/com/nexmo/client/verify/CheckResult.java index ee627c34a..90ffaf325 100644 --- a/src/main/java/com/nexmo/client/verify/CheckResult.java +++ b/src/main/java/com/nexmo/client/verify/CheckResult.java @@ -21,10 +21,6 @@ */ package com.nexmo.client.verify; -/** - * @deprecated Relies on XML Endpoint, use {@link CheckResponse} - */ -@Deprecated public class CheckResult extends BaseResult { private String requestId; private String eventId; diff --git a/src/main/java/com/nexmo/client/verify/SearchResult.java b/src/main/java/com/nexmo/client/verify/SearchResult.java index 831002e7c..2fd43febf 100644 --- a/src/main/java/com/nexmo/client/verify/SearchResult.java +++ b/src/main/java/com/nexmo/client/verify/SearchResult.java @@ -21,14 +21,9 @@ */ package com.nexmo.client.verify; - import java.util.Date; import java.util.List; -/** - * @deprecated Relies on XML Endpoint, use {@link SearchVerifyResponse} - */ -@Deprecated public class SearchResult extends BaseResult { private String requestId; private String accountId; @@ -43,14 +38,15 @@ public class SearchResult extends BaseResult { private Date lastEventDate; private List checks; - /** Used to define a verify check attempt. */ + /** + * Used to define a verify check attempt. + */ public static class VerifyCheck implements java.io.Serializable { - + private static final long serialVersionUID = -5933303841261513099L; public enum Status { - VALID, - INVALID, + VALID, INVALID, } private final Date date; @@ -58,10 +54,7 @@ public enum Status { private final Status status; private final String ipAddress; - public VerifyCheck(Date date, - String code, - Status status, - String ipAddress) { + public VerifyCheck(Date date, String code, Status status, String ipAddress) { this.date = date; this.code = code; this.status = status; @@ -88,15 +81,12 @@ public String getIpAddress() { public String toString() { return "VerifyCheck [status=" + this.status + ", code=" + this.code + ", date=" + this.date + "]"; } - + } public enum VerificationStatus { - - IN_PROGRESS("IN PROGRESS"), - SUCCESS, - FAILED, - EXPIRED; + + IN_PROGRESS("IN PROGRESS"), SUCCESS, FAILED, EXPIRED; private final String name; @@ -116,24 +106,24 @@ public String getName() { public String toString() { return getName(); } - + } public SearchResult(final int status, - final String requestId, - final String accountId, - final VerificationStatus verificationStatus, - final String number, - final float price, - final String currency, - final String senderId, - final Date dateSubmitted, - final Date dateFinalized, - final Date firstEventDate, - final Date lastEventDate, - final List checks, - final String errorText, - final boolean temporaryError) { + final String requestId, + final String accountId, + final VerificationStatus verificationStatus, + final String number, + final float price, + final String currency, + final String senderId, + final Date dateSubmitted, + final Date dateFinalized, + final Date firstEventDate, + final Date lastEventDate, + final List checks, + final String errorText, + final boolean temporaryError) { super(status, errorText, temporaryError); this.requestId = requestId; this.accountId = accountId; @@ -205,5 +195,5 @@ public List getChecks() { public String toString() { return "SearchResult [status=" + getStatus() + ", requestId=" + this.requestId + ", verificationStatus=" + this.verificationStatus + "]"; } - + } From 139b3488a4689a2e0ee3b35b7c02f2448ad659aa Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 6 Jul 2018 13:10:54 -0400 Subject: [PATCH 19/21] Fallback to HTTP when getting dependencies from jcenter on Java 7. --- build.gradle | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 265638026..ccf24d514 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,12 @@ import org.gradle.internal.jvm.Jvm buildscript { repositories { - jcenter() + if (Jvm.current().javaVersion.toString() == "1.7") { + // Fall back to HTTP because the public Oracle and OpenJDK 1.7 versions don't support TLSv1.2 + maven { url "http://jcenter.bintray.com/" } + } else { + jcenter() + } } dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4' From 583c7bf6a8cfbb446d9a1d853d4677da4b0c6506 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 6 Jul 2018 13:16:01 -0400 Subject: [PATCH 20/21] Update CHANGELOG from Development to release. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a300313f..a4b09b34d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Development] +## [3.6.0] - 2018-07-06 ### Added - Added `getSmsPrice` to `AccountClient` for getting SMS pricing for a country. - Added `getVoicePrice` to `AccountClient` for getting voice pricing for a country. From c0e342491b483d5d913d798b4cba612d59968a72 Mon Sep 17 00:00:00 2001 From: Steve Crow Date: Fri, 6 Jul 2018 13:16:07 -0400 Subject: [PATCH 21/21] =?UTF-8?q?Bump=20version:=203.5.0=20=E2=86=92=203.6?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- README.md | 4 ++-- build.gradle | 2 +- src/main/java/com/nexmo/client/HttpWrapper.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index bbd8ea5e4..257cbaa75 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 3.5.0 +current_version = 3.6.0 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P[a-z]+))? serialize = {major}.{minor}.{patch} diff --git a/README.md b/README.md index 3cbf77e7c..c1aebe1da 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ repositories { } dependencies { - compile 'com.nexmo:client:3.5.0' + compile 'com.nexmo:client:3.6.0' } ``` @@ -40,7 +40,7 @@ Add the following to the correct place in your project's POM file: com.nexmo client - 3.5.0 + 3.6.0 ``` diff --git a/build.gradle b/build.gradle index ccf24d514..0ac4fa73b 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'eclipse' group = "com.nexmo" archivesBaseName = "client" -version = "3.5.0" +version = "3.6.0" sourceCompatibility = "1.7" targetCompatibility = "1.7" diff --git a/src/main/java/com/nexmo/client/HttpWrapper.java b/src/main/java/com/nexmo/client/HttpWrapper.java index 39d936392..16f332ada 100644 --- a/src/main/java/com/nexmo/client/HttpWrapper.java +++ b/src/main/java/com/nexmo/client/HttpWrapper.java @@ -85,7 +85,7 @@ protected HttpClient createHttpClient() { return HttpClientBuilder.create() .setConnectionManager(connectionManager) - .setUserAgent("nexmo-java/3.5.0") + .setUserAgent("nexmo-java/3.6.0") .setDefaultRequestConfig(requestConfig) .build(); }