From fb8fce8548aeaeb8c9d879c54b090955bb03dbfa Mon Sep 17 00:00:00 2001 From: Mark Smith Date: Thu, 19 Oct 2017 14:50:19 +0100 Subject: [PATCH] 3.0.0 Release (#125) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Missing CallStatus values (#75) * Add setter for statusReportRequired. Resolves #71 (#76) * Add setter for statusReportRequired. Resolves #71 * Fix the Travis container version. (#107) * Numbers (#114) * Implementation of NumbersClient.listNumbers. * Add setters to OwnedNumber * Full test coverage. * Suggested quality improvements. * Update CHANGELOG.md * NumbersClient.searchNumbers implementation. * Tests for searchNumbers. * Update CHANGELOG.md * Make SearchPattern a top-level class. * Implementation and tests for NumbersClient.cancelNumber * Update CHANGELOG.md * Working on error-handling. * Handle error responses from server. * Fix javadoc and add javadoc to public classes. * Document cancelNumber. * Remove spurious imports. * Initial implementation of buy number. * Ensure sensible default response values if actual HTTP response is empty dict. * Fix copy-paste javadoc mistake. * Update changelog. * Verify control (#115) * Internal implementation. * Public interface. * Update CHANGELOG.md * Add AccountClient and code for getBalance. (#105) * Add AccountClient and code for getBalance. * Test coverage * Attempt to get tests running under JDK7 * 100% coverage. * Revert "Attempt to get tests running under JDK7" This reverts commit ecf5810a2358683441ab9de6b22be4ead8a48db6. * Update CHANGELOG * Improve test for AccountClient * Use void in BalanceEndpoint (#117) * Applications Client (#119) * Application endpoints - create, update and delete. * Add get application and list applications. * Add ApplicationClient and associated tests. * Add details to CHANGELOG * Fixup imports etc. * Add javadoc for ApplicationClient. * Unused import. * Test quality improvements. * Modify call extension (#116) * All implemented. * Minor refactoring and more tests. * Update the CHANGELOG. * Fix silly Javadoc bug. * A little more coverage. * Replace action string with enum ModifyCallAction * Fix javadoc. * Remove unused import. * Update number (#121) * Implement update number. * Tests passing. * Add user-facing interface and more tests. * Update CHANGELOG.md * Add short description of setHttpClient (#104) * Add short description of setHttpClient * Add javadoc mirroring the README change. * Http error responses (#123) * Error status codes now throw HttpResponseException. * Test refactoring and tests for throttle responses. * Tests for the new behaviour. * Update CHANGELOG * Code cleanup. * Sms coverage (#120) * Improve error output and add Hamcrest assertion library. * searchSms and searchRejected * Add code to SmsClient * SmsClient cleanup and coverage. * Remove needless import. * Update Changelog. * Bump version: 2.0.2 → 3.0.0 * Update CHANGELOG.md --- .bumpversion.cfg | 2 +- .travis.yml | 4 +- CHANGELOG.md | 22 ++ README.md | 11 +- build.gradle | 9 +- .../java/com/nexmo/client/HttpWrapper.java | 2 +- .../client/NexmoBadRequestException.java | 40 +++ .../java/com/nexmo/client/NexmoClient.java | 28 +++ .../client/NexmoMethodFailedException.java | 40 +++ .../nexmo/client/account/AccountClient.java | 49 ++++ .../nexmo/client/account/BalanceEndpoint.java | 66 +++++ .../nexmo/client/account/BalanceResponse.java | 59 +++++ .../applications/ApplicationClient.java | 104 ++++++++ .../applications/ApplicationDetails.java | 66 +++++ .../client/applications/ApplicationKeys.java | 41 ++++ .../client/applications/ApplicationType.java | 32 +++ .../CreateApplicationRequest.java | 96 ++++++++ .../applications/ListApplicationsRequest.java | 55 +++++ .../ListApplicationsResponse.java | 73 ++++++ .../UpdateApplicationRequest.java | 102 ++++++++ .../applications/VoiceApplicationDetails.java | 35 +++ .../nexmo/client/applications/WebHook.java | 47 ++++ .../endpoints/ApplicationsEndpoint.java | 69 ++++++ .../endpoints/CreateApplicationMethod.java | 66 +++++ .../endpoints/DeleteApplicationMethod.java | 64 +++++ .../endpoints/EmbeddedApplicationDetails.java | 36 +++ .../endpoints/GetApplicationEndpoint.java | 64 +++++ .../endpoints/ListApplicationsEndpoint.java | 66 +++++ .../endpoints/UpdateApplicationMethod.java | 66 +++++ .../nexmo/client/numbers/AvailableNumber.java | 73 ++++++ .../client/numbers/BuyNumberEndpoint.java | 72 ++++++ .../client/numbers/BuyNumberRequest.java | 46 ++++ .../client/numbers/BuyNumberResponse.java | 52 ++++ .../client/numbers/CancelNumberEndpoint.java | 73 ++++++ .../client/numbers/CancelNumberRequest.java | 47 ++++ .../client/numbers/CancelNumberResponse.java | 56 +++++ .../client/numbers/ListNumbersEndpoint.java | 68 ++++++ .../client/numbers/ListNumbersFilter.java | 95 +++++++ .../client/numbers/ListNumbersResponse.java | 55 +++++ .../nexmo/client/numbers/NumbersClient.java | 142 +++++++++++ .../com/nexmo/client/numbers/OwnedNumber.java | 91 +++++++ .../client/numbers/SearchNumbersEndpoint.java | 73 ++++++ .../client/numbers/SearchNumbersFilter.java | 119 +++++++++ .../client/numbers/SearchNumbersResponse.java | 61 +++++ .../nexmo/client/numbers/SearchPattern.java | 41 ++++ .../client/numbers/UpdateNumberEndpoint.java | 70 ++++++ .../client/numbers/UpdateNumberRequest.java | 115 +++++++++ .../client/numbers/UpdateNumberResponse.java | 54 ++++ .../com/nexmo/client/sms/RejectedMessage.java | 65 +++++ .../sms/SearchRejectedMessagesEndpoint.java | 64 +++++ .../sms/SearchRejectedMessagesRequest.java | 45 ++++ .../sms/SearchRejectedMessagesResponse.java | 53 ++++ .../nexmo/client/sms/SearchSmsRequest.java | 28 +++ .../nexmo/client/sms/SearchSmsResponse.java | 53 ++++ .../java/com/nexmo/client/sms/SmsClient.java | 71 +++++- .../client/sms/SmsDateSearchRequest.java | 45 ++++ .../java/com/nexmo/client/sms/SmsDetails.java | 96 ++++++++ .../nexmo/client/sms/SmsIdSearchRequest.java | 51 ++++ .../nexmo/client/sms/SmsSearchEndpoint.java | 64 +++++ .../nexmo/client/sms/messages/Message.java | 17 +- .../nexmo/client/verify/ControlRequest.java | 49 ++++ .../nexmo/client/verify/ControlResponse.java | 70 ++++++ .../com/nexmo/client/verify/VerifyClient.java | 29 +++ .../client/verify/VerifyControlCommand.java | 41 ++++ .../nexmo/client/verify/VerifyException.java | 43 ++++ .../verify/endpoints/ControlEndpoint.java | 75 ++++++ .../verify/endpoints/SearchEndpoint.java | 4 +- .../verify/endpoints/VerifyCheckMethod.java | 9 +- .../com/nexmo/client/voice/CallModifier.java | 24 +- .../com/nexmo/client/voice/CallStatus.java | 8 +- .../nexmo/client/voice/ModifyCallAction.java | 45 ++++ .../nexmo/client/voice/ModifyCallPayload.java | 11 +- .../client/voice/ModifyCallResponse.java | 2 +- .../client/voice/TransferCallPayload.java | 38 +++ .../client/voice/TransferDestination.java | 56 +++++ .../com/nexmo/client/voice/VoiceClient.java | 51 +++- .../voice/endpoints/AbstractMethod.java | 4 +- .../client/voice/endpoints/CallsEndpoint.java | 10 +- .../voice/endpoints/CreateCallMethod.java | 6 +- .../voice/endpoints/ListCallsMethod.java | 6 +- .../voice/endpoints/ModifyCallMethod.java | 4 +- .../voice/endpoints/ReadCallMethod.java | 6 +- .../voice/endpoints/SendDtmfMethod.java | 6 +- .../voice/endpoints/StartStreamMethod.java | 6 +- .../voice/endpoints/StartTalkMethod.java | 4 +- .../voice/endpoints/StopStreamMethod.java | 4 +- .../voice/endpoints/StopTalkMethod.java | 6 +- src/test/java/com/nexmo/client/TestUtils.java | 33 ++- .../client/account/AccountClientTest.java | 49 ++++ .../client/account/BalanceEndpointTest.java | 91 +++++++ .../client/account/BalanceResponseTest.java | 39 +++ .../applications/ApplicationClientTest.java | 231 ++++++++++++++++++ .../applications/ApplicationTypeTest.java | 38 +++ .../endpoints/ApplicationDetailsTest.java | 40 +++ .../CreateApplicationMethodTest.java | 140 +++++++++++ .../DeleteApplicationMethodTest.java | 65 +++++ .../endpoints/GetApplicationEndpointTest.java | 114 +++++++++ .../ListApplicationsEndpointTest.java | 158 ++++++++++++ .../ListApplicationsResponseTest.java | 40 +++ .../UpdateApplicationMethodTest.java | 144 +++++++++++ .../client/numbers/BuyNumberEndpointTest.java | 111 +++++++++ .../BuyNumberRequestAndResponseTest.java | 57 +++++ .../numbers/CancelNumberEndpointTest.java | 104 ++++++++ .../CancelNumberRequestAndResponseTest.java | 56 +++++ .../numbers/ListNumbersEndpointTest.java | 100 ++++++++ .../ListNumbersFilterAndResponseTest.java | 87 +++++++ .../client/numbers/NumbersClientTest.java | 194 +++++++++++++++ .../numbers/SearchNumbersEndpointTest.java | 127 ++++++++++ .../SearchNumbersFilterAndResponseTest.java | 91 +++++++ .../numbers/UpdateNumberEndpointTest.java | 119 +++++++++ .../numbers/UpdateNumberResponseTest.java | 39 +++ .../SearchRejectedMessagesEndpointTest.java | 97 ++++++++ .../SearchRejectedMessagesResponseTest.java | 39 +++ .../client/sms/SearchSmsEndpointTest.java | 160 ++++++++++++ .../client/sms/SearchSmsResponseTest.java | 39 +++ .../client/sms/SendMessageEndpointTest.java | 13 + .../com/nexmo/client/sms/SmsClientTest.java | 108 ++++++++ .../nexmo/client/verify/VerifyClientTest.java | 4 +- .../verify/endpoints/ControlEndpointTest.java | 95 +++++++ .../verify/endpoints/ControlResponseTest.java | 52 ++++ .../verify/endpoints/SearchEndpointTest.java | 54 ++-- .../nexmo/client/voice/CallModifierTest.java | 15 +- .../client/voice/SendDtmfMethodTest.java | 5 + .../client/voice/TransferCallPayloadTest.java | 41 ++++ .../nexmo/client/voice/VoiceClientTest.java | 18 +- .../client/voice/endpoints/CallInfoTest.java | 83 ++++++- .../voice/endpoints/CreateCallMethodTest.java | 7 +- .../voice/endpoints/ListCallsMethodTest.java | 10 +- .../voice/endpoints/ModifyCallMethodTest.java | 83 ++++++- .../voice/endpoints/ReadCallMethodTest.java | 13 +- 130 files changed, 7160 insertions(+), 129 deletions(-) create mode 100644 src/main/java/com/nexmo/client/NexmoBadRequestException.java create mode 100644 src/main/java/com/nexmo/client/NexmoMethodFailedException.java create mode 100644 src/main/java/com/nexmo/client/account/AccountClient.java create mode 100644 src/main/java/com/nexmo/client/account/BalanceEndpoint.java create mode 100644 src/main/java/com/nexmo/client/account/BalanceResponse.java create mode 100644 src/main/java/com/nexmo/client/applications/ApplicationClient.java create mode 100644 src/main/java/com/nexmo/client/applications/ApplicationDetails.java create mode 100644 src/main/java/com/nexmo/client/applications/ApplicationKeys.java create mode 100644 src/main/java/com/nexmo/client/applications/ApplicationType.java create mode 100644 src/main/java/com/nexmo/client/applications/CreateApplicationRequest.java create mode 100644 src/main/java/com/nexmo/client/applications/ListApplicationsRequest.java create mode 100644 src/main/java/com/nexmo/client/applications/ListApplicationsResponse.java create mode 100644 src/main/java/com/nexmo/client/applications/UpdateApplicationRequest.java create mode 100644 src/main/java/com/nexmo/client/applications/VoiceApplicationDetails.java create mode 100644 src/main/java/com/nexmo/client/applications/WebHook.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/ApplicationsEndpoint.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/CreateApplicationMethod.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethod.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/EmbeddedApplicationDetails.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/GetApplicationEndpoint.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpoint.java create mode 100644 src/main/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethod.java create mode 100644 src/main/java/com/nexmo/client/numbers/AvailableNumber.java create mode 100644 src/main/java/com/nexmo/client/numbers/BuyNumberEndpoint.java create mode 100644 src/main/java/com/nexmo/client/numbers/BuyNumberRequest.java create mode 100644 src/main/java/com/nexmo/client/numbers/BuyNumberResponse.java create mode 100644 src/main/java/com/nexmo/client/numbers/CancelNumberEndpoint.java create mode 100644 src/main/java/com/nexmo/client/numbers/CancelNumberRequest.java create mode 100644 src/main/java/com/nexmo/client/numbers/CancelNumberResponse.java create mode 100644 src/main/java/com/nexmo/client/numbers/ListNumbersEndpoint.java create mode 100644 src/main/java/com/nexmo/client/numbers/ListNumbersFilter.java create mode 100644 src/main/java/com/nexmo/client/numbers/ListNumbersResponse.java create mode 100644 src/main/java/com/nexmo/client/numbers/NumbersClient.java create mode 100644 src/main/java/com/nexmo/client/numbers/OwnedNumber.java create mode 100644 src/main/java/com/nexmo/client/numbers/SearchNumbersEndpoint.java create mode 100644 src/main/java/com/nexmo/client/numbers/SearchNumbersFilter.java create mode 100644 src/main/java/com/nexmo/client/numbers/SearchNumbersResponse.java create mode 100644 src/main/java/com/nexmo/client/numbers/SearchPattern.java create mode 100644 src/main/java/com/nexmo/client/numbers/UpdateNumberEndpoint.java create mode 100644 src/main/java/com/nexmo/client/numbers/UpdateNumberRequest.java create mode 100644 src/main/java/com/nexmo/client/numbers/UpdateNumberResponse.java create mode 100644 src/main/java/com/nexmo/client/sms/RejectedMessage.java create mode 100644 src/main/java/com/nexmo/client/sms/SearchRejectedMessagesEndpoint.java create mode 100644 src/main/java/com/nexmo/client/sms/SearchRejectedMessagesRequest.java create mode 100644 src/main/java/com/nexmo/client/sms/SearchRejectedMessagesResponse.java create mode 100644 src/main/java/com/nexmo/client/sms/SearchSmsRequest.java create mode 100644 src/main/java/com/nexmo/client/sms/SearchSmsResponse.java create mode 100644 src/main/java/com/nexmo/client/sms/SmsDateSearchRequest.java create mode 100644 src/main/java/com/nexmo/client/sms/SmsDetails.java create mode 100644 src/main/java/com/nexmo/client/sms/SmsIdSearchRequest.java create mode 100644 src/main/java/com/nexmo/client/sms/SmsSearchEndpoint.java create mode 100644 src/main/java/com/nexmo/client/verify/ControlRequest.java create mode 100644 src/main/java/com/nexmo/client/verify/ControlResponse.java create mode 100644 src/main/java/com/nexmo/client/verify/VerifyControlCommand.java create mode 100644 src/main/java/com/nexmo/client/verify/VerifyException.java create mode 100644 src/main/java/com/nexmo/client/verify/endpoints/ControlEndpoint.java create mode 100644 src/main/java/com/nexmo/client/voice/ModifyCallAction.java create mode 100644 src/main/java/com/nexmo/client/voice/TransferCallPayload.java create mode 100644 src/main/java/com/nexmo/client/voice/TransferDestination.java create mode 100644 src/test/java/com/nexmo/client/account/AccountClientTest.java create mode 100644 src/test/java/com/nexmo/client/account/BalanceEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/account/BalanceResponseTest.java create mode 100644 src/test/java/com/nexmo/client/applications/ApplicationClientTest.java create mode 100644 src/test/java/com/nexmo/client/applications/ApplicationTypeTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/ApplicationDetailsTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/CreateApplicationMethodTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethodTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/GetApplicationEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsResponseTest.java create mode 100644 src/test/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethodTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/BuyNumberEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/BuyNumberRequestAndResponseTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/CancelNumberEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/CancelNumberRequestAndResponseTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/ListNumbersEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/ListNumbersFilterAndResponseTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/NumbersClientTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/SearchNumbersEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/SearchNumbersFilterAndResponseTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/UpdateNumberEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/numbers/UpdateNumberResponseTest.java create mode 100644 src/test/java/com/nexmo/client/sms/SearchRejectedMessagesEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/sms/SearchRejectedMessagesResponseTest.java create mode 100644 src/test/java/com/nexmo/client/sms/SearchSmsEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/sms/SearchSmsResponseTest.java create mode 100644 src/test/java/com/nexmo/client/verify/endpoints/ControlEndpointTest.java create mode 100644 src/test/java/com/nexmo/client/verify/endpoints/ControlResponseTest.java create mode 100644 src/test/java/com/nexmo/client/voice/TransferCallPayloadTest.java diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 9e716944f..4bb9ff4c9 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = True -current_version = 2.0.2 +current_version = 3.0.0 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P[a-z]+))? serialize = {major}.{minor}.{patch} diff --git a/.travis.yml b/.travis.yml index 78c494b08..727c7ff58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ --- sudo: false +dist: precise language: java jdk: - oraclejdk8 - oraclejdk7 - #- openjdk6 after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file + - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e5af9fc..aeb6af683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,28 @@ 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/). +## [3.0.0] - 2017-10-19 + +### Changed +- `ModifyCallPayload.action` is now a value of the enum `ModifyCallPayload.Action`. +- All calls now throw `HttpResponseException` if an abnormal HTTP status code is returned from the Nexmo API. + +### Fixed +- Added missing values for CallStatus: FAILED, REJECTED, BUSY & CANCELLED + +### Added +- Add missing setter for the Message.statusReportRequired property. +- Add `AccountClient.getBalance` method for getting an account balance. +- Add `NumbersClient.listNumbers` method. +- Add `NumbersClient.searchNumbers` method. +- Add `NumbersClient.cancelNumber` method. +- Add `NumbersClient.buyNumber` method. +- Add `NumbersClient.updateNumber` and `NumbersClient.linkNumber`. +- Add the ability to mute, unmute, earmuff, unearmuff and transfer an ongoing call. +- Add `VerifyClient.advanceVerification` and `VerifyClient.cancelVerification` +- Add `ApplicationClient` end methods for creating, updating, deleting, listing and getting configured applications. +- Add extra endpoints for searching SMS messages. + ## [2.0.2] - 2017-05-04 ### Fixed - All URL-encoded PUT and POST requests are now UTF-8 instead of ISO-8859-1. diff --git a/README.md b/README.md index 89545831e..0d04a94a4 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ repositories { } dependencies { - compile 'com.nexmo:client:2.0.2' + compile 'com.nexmo:client:3.0.0' } ``` @@ -41,7 +41,7 @@ Add the following to the correct place in your project's POM file: com.nexmo client - 2.0.2 + 3.0.0 ``` @@ -177,6 +177,13 @@ When the user enters the code they received, you can check it like this: client.getVerifyClient().check(ongoingVerify.getRequestId(), CODE) ``` +## Custom HTTP Configuration + +If you need to configure the Apache HttpClient used for making requests, you can +call `NexmoClient.setHttpClient()` to supply your custom configured object. This +can be useful, for example, if you must use an HTTP proxy to make requests. + + ## API Coverage * Account diff --git a/build.gradle b/build.gradle index 94055e7b5..516bec7ec 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ apply plugin: 'eclipse' group = "com.nexmo" archivesBaseName = "client" -version = "2.0.2" +version = "3.0.0" sourceCompatibility = "1.7" targetCompatibility = "1.7" @@ -38,11 +38,14 @@ dependencies { testCompile "javax.servlet:javax.servlet-api:3.1.0" testCompile 'junit:junit:4.4' testCompile "org.mockito:mockito-core:2.7.1" + testCompile 'org.hamcrest:hamcrest-all:1.3' } test { - // testLogging.minGranularity = 2 - // testLogging.showStandardStreams = true + testLogging { + events "failed" + exceptionFormat "full" + } } javadoc { diff --git a/src/main/java/com/nexmo/client/HttpWrapper.java b/src/main/java/com/nexmo/client/HttpWrapper.java index 484a289f4..9db3971d9 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/2.0.2") + .setUserAgent("nexmo-java/3.0.0") .setDefaultRequestConfig(requestConfig) .build(); } diff --git a/src/main/java/com/nexmo/client/NexmoBadRequestException.java b/src/main/java/com/nexmo/client/NexmoBadRequestException.java new file mode 100644 index 000000000..fd4d2d759 --- /dev/null +++ b/src/main/java/com/nexmo/client/NexmoBadRequestException.java @@ -0,0 +1,40 @@ +/* + * 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; + +public class NexmoBadRequestException extends NexmoClientException { + public NexmoBadRequestException() { + super(); + } + + public NexmoBadRequestException(String message) { + super(message); + } + + public NexmoBadRequestException(String message, Throwable cause) { + super(message, cause); + } + + public NexmoBadRequestException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/nexmo/client/NexmoClient.java b/src/main/java/com/nexmo/client/NexmoClient.java index dd93d0964..5486d69ad 100644 --- a/src/main/java/com/nexmo/client/NexmoClient.java +++ b/src/main/java/com/nexmo/client/NexmoClient.java @@ -22,8 +22,11 @@ package com.nexmo.client; +import com.nexmo.client.account.AccountClient; +import com.nexmo.client.applications.ApplicationClient; import com.nexmo.client.auth.AuthMethod; import com.nexmo.client.insight.InsightClient; +import com.nexmo.client.numbers.NumbersClient; import com.nexmo.client.sms.SmsClient; import com.nexmo.client.sns.SnsClient; import com.nexmo.client.verify.VerifyClient; @@ -40,7 +43,10 @@ * clients for all of the Nexmo APIs. */ public class NexmoClient { + private final AccountClient account; + private final ApplicationClient application; private final InsightClient insight; + private final NumbersClient numbers; private final SmsClient sms; private final VoiceClient voice; private final VerifyClient verify; @@ -51,21 +57,43 @@ public class NexmoClient { public NexmoClient(AuthMethod... authMethods) { this.httpWrapper = new HttpWrapper(authMethods); + this.account = new AccountClient(this.httpWrapper); + this.application = new ApplicationClient(this.httpWrapper); this.insight = new InsightClient(this.httpWrapper); + this.numbers = new NumbersClient(this.httpWrapper); this.verify = new VerifyClient(this.httpWrapper); this.voice = new VoiceClient(this.httpWrapper); this.sms = new SmsClient(this.httpWrapper); this.sns = new SnsClient(this.httpWrapper); } + /** + * Provide an HttpClient that will be used to make requests to the Nexmo API. + *

+ * This can be useful, for example, if you must use an HTTP proxy to make requests. + * + * @param client A custom-configured HttpClient instance. + */ public void setHttpClient(HttpClient client) { this.httpWrapper.setHttpClient(client); } + public AccountClient getAccountClient() { + return this.account; + } + + public ApplicationClient getApplicationClient() { + return this.application; + } + public InsightClient getInsightClient() { return this.insight; } + public NumbersClient getNumbersClient() { + return this.numbers; + } + public SmsClient getSmsClient() { return this.sms; } diff --git a/src/main/java/com/nexmo/client/NexmoMethodFailedException.java b/src/main/java/com/nexmo/client/NexmoMethodFailedException.java new file mode 100644 index 000000000..caa009028 --- /dev/null +++ b/src/main/java/com/nexmo/client/NexmoMethodFailedException.java @@ -0,0 +1,40 @@ +/* + * 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; + +public class NexmoMethodFailedException extends NexmoClientException { + public NexmoMethodFailedException() { + super(); + } + + public NexmoMethodFailedException(String message) { + super(message); + } + + public NexmoMethodFailedException(String message, Throwable cause) { + super(message, cause); + } + + public NexmoMethodFailedException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/nexmo/client/account/AccountClient.java b/src/main/java/com/nexmo/client/account/AccountClient.java new file mode 100644 index 000000000..6f86466ba --- /dev/null +++ b/src/main/java/com/nexmo/client/account/AccountClient.java @@ -0,0 +1,49 @@ +/* + * 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.account; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClient; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; + +/** + * 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 { + protected BalanceEndpoint balance; + + /** + * Constructor. + * + * @param httpWrapper (required) shared HTTP wrapper object used for making REST calls. + */ + public AccountClient(HttpWrapper httpWrapper) { + this.balance = new BalanceEndpoint(httpWrapper); + } + + public BalanceResponse getBalance() throws IOException, NexmoClientException { + return this.balance.execute(); + } +} diff --git a/src/main/java/com/nexmo/client/account/BalanceEndpoint.java b/src/main/java/com/nexmo/client/account/BalanceEndpoint.java new file mode 100644 index 000000000..9f8acdf08 --- /dev/null +++ b/src/main/java/com/nexmo/client/account/BalanceEndpoint.java @@ -0,0 +1,66 @@ +/* + * 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.account; + +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 BalanceEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/account/get-balance"; + + private String uri = DEFAULT_URI; + + public BalanceEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(Void request) throws NexmoClientException, UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri); + return requestBuilder; + } + + public BalanceResponse execute() throws NexmoClientException, IOException { + return this.execute(null); + } + + @Override + public BalanceResponse parseResponse(HttpResponse response) throws IOException { + return BalanceResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/account/BalanceResponse.java b/src/main/java/com/nexmo/client/account/BalanceResponse.java new file mode 100644 index 000000000..05461f05b --- /dev/null +++ b/src/main/java/com/nexmo/client/account/BalanceResponse.java @@ -0,0 +1,59 @@ +/* + * 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.account; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BalanceResponse { + private double value; + private boolean autoReload; + + public BalanceResponse(@JsonProperty("value") double value, @JsonProperty("autoReload") boolean autoReload) { + this.value = value; + this.autoReload = autoReload; + } + + @JsonProperty("value") + public double getValue() { + return value; + } + + @JsonProperty("autoReload") + public boolean isAutoReload() { + return autoReload; + } + + public static BalanceResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, BalanceResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce BalanceResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/applications/ApplicationClient.java b/src/main/java/com/nexmo/client/applications/ApplicationClient.java new file mode 100644 index 000000000..139224dd8 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ApplicationClient.java @@ -0,0 +1,104 @@ +/* + * 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.applications; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClient; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.endpoints.ApplicationsEndpoint; + +import java.io.IOException; + +/** + * A client for talking to the Nexmo Number Applications API. + * The standard way to obtain an instance of this class is to + * use + * {@link NexmoClient#getApplicationClient()}. + */ +public class ApplicationClient { + protected ApplicationsEndpoint applications; + + /** + * Constructor. + * + * @param httpWrapper (required) shared HTTP wrapper object used for making REST calls. + */ + public ApplicationClient(HttpWrapper httpWrapper) { + this.applications = new ApplicationsEndpoint(httpWrapper); + } + + /** + * Create a new Application. + * + * @param request A CreateApplicationRequest describing the application to be created. + * @return An ApplicationDetails object describing the newly created application, including generated private and + * public keys. + */ + public ApplicationDetails createApplication(CreateApplicationRequest request) + throws IOException, NexmoClientException { + return this.applications.post(request); + } + + /** + * Update an existing application with the provided details. + * + * @param request An UpdateApplicationRequest describing the new application details. + * @return An ApplicationDetails object describing the newly modified application. + */ + public ApplicationDetails updateApplication(UpdateApplicationRequest request) + throws IOException, NexmoClientException { + return this.applications.put(request); + } + + /** + * List the applications associated with the authenticated account. By default returns the first page of + * application objects. + * + * @param request A ListApplicationsRequest object containing the required paging information. + * @return A ListApplicationsResponse, which is an Iterator of ApplicationDetails objects. + */ + public ListApplicationsResponse listApplications(ListApplicationsRequest request) + throws IOException, NexmoClientException { + return this.applications.get(request); + } + + /** + * Obtain the details of an existing application. + * + * @param applicationId The id of the application + * @return An ApplicationDetails object describing the requested application. + */ + public ApplicationDetails getApplication(String applicationId) + throws IOException, NexmoClientException { + return this.applications.get(applicationId); + } + + /** + * Delete an application. + * + * @param applicationId The ID of the application to be deleted. + */ + public void deleteApplication(String applicationId) + throws IOException, NexmoClientException { + this.applications.delete(applicationId); + } +} diff --git a/src/main/java/com/nexmo/client/applications/ApplicationDetails.java b/src/main/java/com/nexmo/client/applications/ApplicationDetails.java new file mode 100644 index 000000000..26a9806b0 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ApplicationDetails.java @@ -0,0 +1,66 @@ +/* + * 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.applications; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApplicationDetails { + private String id; + private String name; + private VoiceApplicationDetails voiceApplicationDetails; + private ApplicationKeys keys; + + public static ApplicationDetails fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, ApplicationDetails.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce ApplicationDetails from json.", jpe); + } + } + + @JsonProperty("id") + public String getId() { + return id; + } + + @JsonProperty("name") + public String getName() { + return name; + } + + @JsonProperty("voice") + public VoiceApplicationDetails getVoiceApplicationDetails() { + return voiceApplicationDetails; + } + + @JsonProperty("keys") + public ApplicationKeys getKeys() { + return keys; + } +} diff --git a/src/main/java/com/nexmo/client/applications/ApplicationKeys.java b/src/main/java/com/nexmo/client/applications/ApplicationKeys.java new file mode 100644 index 000000000..75f95daf2 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ApplicationKeys.java @@ -0,0 +1,41 @@ +/* + * 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.applications; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApplicationKeys { + private String publicKey; + private String privateKey; + + @JsonProperty("public_key") + public String getPublicKey() { + return publicKey; + } + + @JsonProperty("private_key") + public String getPrivateKey() { + return privateKey; + } +} diff --git a/src/main/java/com/nexmo/client/applications/ApplicationType.java b/src/main/java/com/nexmo/client/applications/ApplicationType.java new file mode 100644 index 000000000..367895a2d --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ApplicationType.java @@ -0,0 +1,32 @@ +/* + * 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.applications; + +public enum ApplicationType { + VOICE; + + + @Override + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/src/main/java/com/nexmo/client/applications/CreateApplicationRequest.java b/src/main/java/com/nexmo/client/applications/CreateApplicationRequest.java new file mode 100644 index 000000000..c1cbdbf55 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/CreateApplicationRequest.java @@ -0,0 +1,96 @@ +/* + * 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.applications; + +import org.apache.http.client.methods.RequestBuilder; + +public class CreateApplicationRequest { + private final String name; + private final ApplicationType type; + private final String answerUrl; + private final String eventUrl; + + private String answerMethod; + private String eventMethod; + + public CreateApplicationRequest(String name, String answerUrl, String eventUrl) { + this(name, ApplicationType.VOICE, answerUrl, null, eventUrl, null); + } + + public CreateApplicationRequest( + String name, ApplicationType type, + String answerUrl, String answerMethod, + String eventUrl, String eventMethod) { + this.name = name; + this.type = type; + this.answerUrl = answerUrl; + this.eventUrl = eventUrl; + this.answerMethod = answerMethod; + this.eventMethod = eventMethod; + } + + public String getName() { + return name; + } + + public ApplicationType getType() { + return type; + } + + public String getAnswerUrl() { + return answerUrl; + } + + public String getEventUrl() { + return eventUrl; + } + + public String getAnswerMethod() { + return answerMethod; + } + + public void setAnswerMethod(String answerMethod) { + this.answerMethod = answerMethod; + } + + public String getEventMethod() { + return eventMethod; + } + + public void setEventMethod(String eventMethod) { + this.eventMethod = eventMethod; + } + + public void addParams(RequestBuilder request) { + request.addParameter("name", this.name) + .addParameter("type", this.type.toString()) + .addParameter("answer_url", this.answerUrl) + .addParameter("event_url", this.eventUrl); + if (this.eventMethod != null) { + request.addParameter("event_method", this.eventMethod); + } + if (this.answerMethod != null) { + request.addParameter("answer_method", this.answerMethod); + } + } + +} diff --git a/src/main/java/com/nexmo/client/applications/ListApplicationsRequest.java b/src/main/java/com/nexmo/client/applications/ListApplicationsRequest.java new file mode 100644 index 000000000..e5364ef8d --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ListApplicationsRequest.java @@ -0,0 +1,55 @@ +/* + * 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.applications; + +import org.apache.http.client.methods.RequestBuilder; + +public class ListApplicationsRequest { + private Integer pageSize; + private Integer pageIndex; + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public Integer getPageIndex() { + return pageIndex; + } + + public void setPageIndex(Integer pageIndex) { + this.pageIndex = pageIndex; + } + + public void addParams(RequestBuilder request) { + if (this.pageSize != null) { + request.addParameter("page_size", this.pageSize.toString()); + } + if (this.pageSize != null) { + request.addParameter("page_index", this.pageIndex.toString()); + } + } + +} diff --git a/src/main/java/com/nexmo/client/applications/ListApplicationsResponse.java b/src/main/java/com/nexmo/client/applications/ListApplicationsResponse.java new file mode 100644 index 000000000..8c0936048 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/ListApplicationsResponse.java @@ -0,0 +1,73 @@ +/* + * 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.applications; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.util.ArrayIterator; +import com.nexmo.client.NexmoUnexpectedException; +import com.nexmo.client.applications.endpoints.EmbeddedApplicationDetails; + +import java.io.IOException; +import java.util.Iterator; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ListApplicationsResponse implements Iterable { + private int count; + private int pageSize; + private int pageIndex; + private EmbeddedApplicationDetails embedded; + + public static ListApplicationsResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, ListApplicationsResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce ListApplicationsResponse from json.", jpe); + } + } + + public int getCount() { + return count; + } + + @JsonProperty("page_size") + public int getPageSize() { + return pageSize; + } + + @JsonProperty("page_index") + public int getPageIndex() { + return pageIndex; + } + + @JsonProperty("_embedded") + public EmbeddedApplicationDetails getEmbedded() { + return embedded; + } + + @Override + public Iterator iterator() { + return new ArrayIterator<>(embedded.getApplicationDetails()); + } +} diff --git a/src/main/java/com/nexmo/client/applications/UpdateApplicationRequest.java b/src/main/java/com/nexmo/client/applications/UpdateApplicationRequest.java new file mode 100644 index 000000000..be8536db0 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/UpdateApplicationRequest.java @@ -0,0 +1,102 @@ +/* + * 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.applications; + +import org.apache.http.client.methods.RequestBuilder; + +public class UpdateApplicationRequest { + private final String applicationId; + private final String name; + private final ApplicationType type; + private final String answerUrl; + private final String eventUrl; + + private String answerMethod; + private String eventMethod; + + public UpdateApplicationRequest(String applicationId, String name, String answerUrl, String eventUrl) { + this(applicationId, name, ApplicationType.VOICE, answerUrl, null, eventUrl, null); + } + + public UpdateApplicationRequest( + String applicationId, String name, ApplicationType type, + String answerUrl, String answerMethod, + String eventUrl, String eventMethod) { + this.applicationId = applicationId; + this.name = name; + this.type = type; + this.answerUrl = answerUrl; + this.eventUrl = eventUrl; + this.answerMethod = answerMethod; + this.eventMethod = eventMethod; + } + + public String getApplicationId() { + return applicationId; + } + + public String getName() { + return name; + } + + public ApplicationType getType() { + return type; + } + + public String getAnswerUrl() { + return answerUrl; + } + + public String getEventUrl() { + return eventUrl; + } + + public String getAnswerMethod() { + return answerMethod; + } + + public void setAnswerMethod(String answerMethod) { + this.answerMethod = answerMethod; + } + + public String getEventMethod() { + return eventMethod; + } + + public void setEventMethod(String eventMethod) { + this.eventMethod = eventMethod; + } + + public void addParams(RequestBuilder request) { + request.addParameter("name", this.name) + .addParameter("type", this.type.toString()) + .addParameter("answer_url", this.answerUrl) + .addParameter("event_url", this.eventUrl); + if (this.eventMethod != null) { + request.addParameter("event_method", this.eventMethod); + } + if (this.answerMethod != null) { + request.addParameter("answer_method", this.answerMethod); + } + } + +} diff --git a/src/main/java/com/nexmo/client/applications/VoiceApplicationDetails.java b/src/main/java/com/nexmo/client/applications/VoiceApplicationDetails.java new file mode 100644 index 000000000..2e3257f55 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/VoiceApplicationDetails.java @@ -0,0 +1,35 @@ +/* + * 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.applications; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class VoiceApplicationDetails { + private WebHook[] webHooks; + + @JsonProperty("webhooks") + public WebHook[] getWebHooks() { + return webHooks; + } +} diff --git a/src/main/java/com/nexmo/client/applications/WebHook.java b/src/main/java/com/nexmo/client/applications/WebHook.java new file mode 100644 index 000000000..e05070f4e --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/WebHook.java @@ -0,0 +1,47 @@ +/* + * 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.applications; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class WebHook { + private String endpointType; + private String endpointUrl; + private String httpMethod; + + @JsonProperty("endpoint_type") + public String getEndpointType() { + return endpointType; + } + + @JsonProperty("endpoint") + public String getEndpointUrl() { + return endpointUrl; + } + + @JsonProperty("http_method") + public String getHttpMethod() { + return httpMethod; + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/ApplicationsEndpoint.java b/src/main/java/com/nexmo/client/applications/endpoints/ApplicationsEndpoint.java new file mode 100644 index 000000000..57c892d7d --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/ApplicationsEndpoint.java @@ -0,0 +1,69 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.*; + +import java.io.IOException; + +public class ApplicationsEndpoint { + private CreateApplicationMethod create; + private UpdateApplicationMethod update; + private GetApplicationEndpoint get; + private ListApplicationsEndpoint list; + private DeleteApplicationMethod delete; + + public ApplicationsEndpoint(HttpWrapper httpWrapper) { + this.create = new CreateApplicationMethod(httpWrapper); + this.update = new UpdateApplicationMethod(httpWrapper); + this.get = new GetApplicationEndpoint(httpWrapper); + this.list = new ListApplicationsEndpoint(httpWrapper); + this.delete = new DeleteApplicationMethod(httpWrapper); + } + + public ApplicationDetails post(CreateApplicationRequest request) + throws IOException, NexmoClientException { + return this.create.execute(request); + } + + public ApplicationDetails put(UpdateApplicationRequest request) + throws IOException, NexmoClientException { + return this.update.execute(request); + } + + public ApplicationDetails get(String applicationId) + throws IOException, NexmoClientException { + return this.get.execute(applicationId); + } + + public ListApplicationsResponse get(ListApplicationsRequest request) + throws IOException, NexmoClientException { + return this.list.execute(request); + } + + public void delete(String applicationId) + throws IOException, NexmoClientException { + this.delete.execute(applicationId); + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/CreateApplicationMethod.java b/src/main/java/com/nexmo/client/applications/endpoints/CreateApplicationMethod.java new file mode 100644 index 000000000..bce10db55 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/CreateApplicationMethod.java @@ -0,0 +1,66 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.ApplicationDetails; +import com.nexmo.client.applications.CreateApplicationRequest; +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 CreateApplicationMethod extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/v1/applications"; + + private String uri = DEFAULT_URI; + + public CreateApplicationMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(CreateApplicationRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.post(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public ApplicationDetails parseResponse(HttpResponse response) throws IOException { + return ApplicationDetails.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethod.java b/src/main/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethod.java new file mode 100644 index 000000000..98998d1ec --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethod.java @@ -0,0 +1,64 @@ +/* + * 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.applications.endpoints; + +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 DeleteApplicationMethod extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/v1/applications"; + + private String uri = DEFAULT_URI; + + public DeleteApplicationMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(String applicationId) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.delete(uri + "/" + applicationId); + return requestBuilder; + } + + @Override + public Void parseResponse(HttpResponse response) throws IOException { + new BasicResponseHandler().handleResponse(response); + return null; + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/EmbeddedApplicationDetails.java b/src/main/java/com/nexmo/client/applications/endpoints/EmbeddedApplicationDetails.java new file mode 100644 index 000000000..a5a27d6b5 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/EmbeddedApplicationDetails.java @@ -0,0 +1,36 @@ +/* + * 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.applications.endpoints; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.nexmo.client.applications.ApplicationDetails; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EmbeddedApplicationDetails { + private ApplicationDetails[] applicationDetails; + + @JsonProperty("applications") + public ApplicationDetails[] getApplicationDetails() { + return applicationDetails; + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/GetApplicationEndpoint.java b/src/main/java/com/nexmo/client/applications/endpoints/GetApplicationEndpoint.java new file mode 100644 index 000000000..562b3b383 --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/GetApplicationEndpoint.java @@ -0,0 +1,64 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.ApplicationDetails; +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 GetApplicationEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/v1/applications"; + + private String uri = DEFAULT_URI; + + public GetApplicationEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(String applicationId) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri + "/" + applicationId); + return requestBuilder; + } + + @Override + public ApplicationDetails parseResponse(HttpResponse response) throws IOException { + return ApplicationDetails.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpoint.java b/src/main/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpoint.java new file mode 100644 index 000000000..4bc367a0f --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpoint.java @@ -0,0 +1,66 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.ListApplicationsRequest; +import com.nexmo.client.applications.ListApplicationsResponse; +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 ListApplicationsEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/v1/applications"; + + private String uri = DEFAULT_URI; + + public ListApplicationsEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(ListApplicationsRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public ListApplicationsResponse parseResponse(HttpResponse response) throws IOException { + return ListApplicationsResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethod.java b/src/main/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethod.java new file mode 100644 index 000000000..496ca8cda --- /dev/null +++ b/src/main/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethod.java @@ -0,0 +1,66 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.applications.ApplicationDetails; +import com.nexmo.client.applications.UpdateApplicationRequest; +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 UpdateApplicationMethod extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/v1/applications"; + + private String uri = DEFAULT_URI; + + public UpdateApplicationMethod(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(UpdateApplicationRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.put(uri + "/" + request.getApplicationId()); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public ApplicationDetails parseResponse(HttpResponse response) throws IOException { + return ApplicationDetails.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/AvailableNumber.java b/src/main/java/com/nexmo/client/numbers/AvailableNumber.java new file mode 100644 index 000000000..5949319dc --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/AvailableNumber.java @@ -0,0 +1,73 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class AvailableNumber { + private String country; + private String msisdn; + private String cost; + private String type; + private String[] features; + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getMsisdn() { + return msisdn; + } + + public void setMsisdn(String msisdn) { + this.msisdn = msisdn; + } + + public String getCost() { + return cost; + } + + public void setCost(String cost) { + this.cost = cost; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String[] getFeatures() { + return features; + } + + public void setFeatures(String[] features) { + this.features = features; + } +} diff --git a/src/main/java/com/nexmo/client/numbers/BuyNumberEndpoint.java b/src/main/java/com/nexmo/client/numbers/BuyNumberEndpoint.java new file mode 100644 index 000000000..e3d779f81 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/BuyNumberEndpoint.java @@ -0,0 +1,72 @@ +/* + * 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.numbers; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.NexmoMethodFailedException; +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 org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class BuyNumberEndpoint extends AbstractMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/number/buy"; + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + private String uri = DEFAULT_URI; + + public BuyNumberEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(BuyNumberRequest request) throws NexmoClientException, UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.post().setUri(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public BuyNumberResponse parseResponse(HttpResponse response) throws IOException, NexmoClientException { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == 400 || statusCode == 420) { + throw new NexmoBadRequestException(EntityUtils.toString(response.getEntity())); + } else if (statusCode >= 500) { + throw new NexmoMethodFailedException(EntityUtils.toString(response.getEntity())); + } + String json = new BasicResponseHandler().handleResponse(response); + return BuyNumberResponse.fromJson(json); + } + + +} diff --git a/src/main/java/com/nexmo/client/numbers/BuyNumberRequest.java b/src/main/java/com/nexmo/client/numbers/BuyNumberRequest.java new file mode 100644 index 000000000..76334053f --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/BuyNumberRequest.java @@ -0,0 +1,46 @@ +/* + * 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.numbers; + +import org.apache.http.client.methods.RequestBuilder; + +public class BuyNumberRequest { + private final String country; + private final String msisdn; + + public BuyNumberRequest(String country, String msisdn) { + this.country = country; + this.msisdn = msisdn; + } + + public String getCountry() { + return country; + } + + public String getMsisdn() { + return msisdn; + } + + public void addParams(RequestBuilder request) { + request.addParameter("country", country).addParameter("msisdn", msisdn); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/BuyNumberResponse.java b/src/main/java/com/nexmo/client/numbers/BuyNumberResponse.java new file mode 100644 index 000000000..51fbdf8b2 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/BuyNumberResponse.java @@ -0,0 +1,52 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +public class BuyNumberResponse { + private String errorCode; + private String errorCodeLabel; + + @JsonProperty("error-code") + public String getErrorCode() { + return errorCode; + } + + @JsonProperty("error-code-label") + public String getErrorCodeLabel() { + return errorCodeLabel; + } + + public static BuyNumberResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, BuyNumberResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce json from BuyNumberResponse object.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/numbers/CancelNumberEndpoint.java b/src/main/java/com/nexmo/client/numbers/CancelNumberEndpoint.java new file mode 100644 index 000000000..add79dfac --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/CancelNumberEndpoint.java @@ -0,0 +1,73 @@ +/* + * 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.numbers; + + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.NexmoMethodFailedException; +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 org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class CancelNumberEndpoint extends AbstractMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/number/cancel"; + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + private String uri = DEFAULT_URI; + + public CancelNumberEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(CancelNumberRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.post().setUri(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public CancelNumberResponse parseResponse(HttpResponse response) throws NexmoClientException, IOException { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == 400 || statusCode == 420) { + throw new NexmoBadRequestException(EntityUtils.toString(response.getEntity())); + } else if (statusCode >= 500) { + throw new NexmoMethodFailedException(EntityUtils.toString(response.getEntity())); + } + + String json = new BasicResponseHandler().handleResponse(response); + return CancelNumberResponse.fromJson(json); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/CancelNumberRequest.java b/src/main/java/com/nexmo/client/numbers/CancelNumberRequest.java new file mode 100644 index 000000000..e6bd5f990 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/CancelNumberRequest.java @@ -0,0 +1,47 @@ +/* + * 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.numbers; + +import org.apache.http.client.methods.RequestBuilder; + +public class CancelNumberRequest { + private final String country; + private final String msisdn; + + public CancelNumberRequest(String country, String msisdn) { + this.country = country; + this.msisdn = msisdn; + } + + public String getCountry() { + return country; + } + + public String getMsisdn() { + return msisdn; + } + + public void addParams(RequestBuilder request) { + request.addParameter("country", country).addParameter("msisdn", msisdn); + + } +} diff --git a/src/main/java/com/nexmo/client/numbers/CancelNumberResponse.java b/src/main/java/com/nexmo/client/numbers/CancelNumberResponse.java new file mode 100644 index 000000000..3388a6f5a --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/CancelNumberResponse.java @@ -0,0 +1,56 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CancelNumberResponse { + private String errorCode; + private String errorCodeLabel; + + @JsonProperty("error-code") + public String getErrorCode() { + return errorCode; + } + + @JsonProperty("error-code-label") + public String getErrorCodeLabel() { + return errorCodeLabel; + } + + public static CancelNumberResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, CancelNumberResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce json from CancelNumberResponse object.", jpe); + } + } + +} diff --git a/src/main/java/com/nexmo/client/numbers/ListNumbersEndpoint.java b/src/main/java/com/nexmo/client/numbers/ListNumbersEndpoint.java new file mode 100644 index 000000000..82a133d93 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/ListNumbersEndpoint.java @@ -0,0 +1,68 @@ +/* + * 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.numbers; + + +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 org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class ListNumbersEndpoint extends AbstractMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/account/numbers"; + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + private String uri = DEFAULT_URI; + + public ListNumbersEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(ListNumbersFilter request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get().setUri(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public ListNumbersResponse parseResponse(HttpResponse response) throws IOException { + String json = new BasicResponseHandler().handleResponse(response); + return ListNumbersResponse.fromJson(json); + } + + public ListNumbersResponse listNumbers(ListNumbersFilter request) throws IOException, NexmoClientException { + return this.execute(request); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/ListNumbersFilter.java b/src/main/java/com/nexmo/client/numbers/ListNumbersFilter.java new file mode 100644 index 000000000..1dd6eb7aa --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/ListNumbersFilter.java @@ -0,0 +1,95 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.http.client.methods.RequestBuilder; + +public class ListNumbersFilter { + private Integer index; + private Integer size; + private String pattern; + private SearchPattern searchPattern; + + public ListNumbersFilter() { + this(null, null, null, null); + } + + public ListNumbersFilter( + @JsonProperty Integer index, + @JsonProperty Integer size, + @JsonProperty String pattern, + @JsonProperty SearchPattern searchPattern) { + this.index = index; + this.size = size; + this.pattern = pattern; + this.searchPattern = searchPattern; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public SearchPattern getSearchPattern() { + return searchPattern; + } + + public void setSearchPattern(SearchPattern searchPattern) { + this.searchPattern = searchPattern; + } + + public void addParams(RequestBuilder request) { + if (index != null) { + request.addParameter("index", index.toString()); + } + if (size != null) { + request.addParameter("size", size.toString()); + } + if (pattern != null) { + request.addParameter("pattern", pattern); + } + if (searchPattern != null) { + request.addParameter("search_pattern", Integer.toString(searchPattern.getValue())); + } + } + +} diff --git a/src/main/java/com/nexmo/client/numbers/ListNumbersResponse.java b/src/main/java/com/nexmo/client/numbers/ListNumbersResponse.java new file mode 100644 index 000000000..dfdde326e --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/ListNumbersResponse.java @@ -0,0 +1,55 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +/** + * Response from a request to list the numbers currently being rented buy an account. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ListNumbersResponse { + private int count = 0; + private OwnedNumber[] numbers = new OwnedNumber[]{}; + + public int getCount() { + return count; + } + + public OwnedNumber[] getNumbers() { + return numbers; + } + + public static ListNumbersResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, ListNumbersResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce json from ListNumbersResponse object.", jpe); + } + } + +} diff --git a/src/main/java/com/nexmo/client/numbers/NumbersClient.java b/src/main/java/com/nexmo/client/numbers/NumbersClient.java new file mode 100644 index 000000000..c6bb747ae --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/NumbersClient.java @@ -0,0 +1,142 @@ +/* + * 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.numbers; + + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; + +import java.io.IOException; + +/** + * A client for accessing the Nexmo API calls that manage phone numbers. + */ +public class NumbersClient { + private ListNumbersEndpoint listNumbers; + private SearchNumbersEndpoint searchNumbers; + private CancelNumberEndpoint cancelNumber; + private BuyNumberEndpoint buyNumber; + private UpdateNumberEndpoint updateNumber; + + public NumbersClient(HttpWrapper httpWrapper) { + this.listNumbers = new ListNumbersEndpoint(httpWrapper); + this.searchNumbers = new SearchNumbersEndpoint(httpWrapper); + this.cancelNumber = new CancelNumberEndpoint(httpWrapper); + this.buyNumber = new BuyNumberEndpoint(httpWrapper); + this.updateNumber = new UpdateNumberEndpoint(httpWrapper); + } + + /** + * Get the first page of phone numbers assigned to the authenticated account. + * + * @return A ListNumbersResponse containing the first 10 phone numbers + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public ListNumbersResponse listNumbers() throws IOException, NexmoClientException { + return this.listNumbers.listNumbers(new ListNumbersFilter()); + } + + /** + * Get a filtered set of numbers assigned to the authenticated account. + * + * @param filter A ListNumbersFilter describing the filters to be applied to the request. + * @return A ListNumbersResponse containing phone numbers matching the supplied filter. + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public ListNumbersResponse listNumbers(ListNumbersFilter filter) throws IOException, NexmoClientException { + return this.listNumbers.listNumbers(filter); + } + + + /** + * Search for available Nexmo Virtual Numbers. + * + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public SearchNumbersResponse searchNumbers(String country) throws IOException, NexmoClientException { + return this.searchNumbers(new SearchNumbersFilter(country)); + } + + /** + * Search for available Nexmo Virtual Numbers. + * + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public SearchNumbersResponse searchNumbers(SearchNumbersFilter filter) throws IOException, NexmoClientException { + return this.searchNumbers.searchNumbers(filter); + } + + /** + * Start renting a Nexmo Virtual Number. + * + * @param country A String containing a 2-character ISO country code. + * @param msisdn The phone number to be bought. + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public void buyNumber(String country, String msisdn) throws IOException, NexmoClientException { + this.buyNumber.execute(new BuyNumberRequest(country, msisdn)); + } + + /** + * Stop renting a Nexmo Virtual Number. + * + * @param country A String containing a 2-character ISO country code. + * @param msisdn The phone number to be cancelled. + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public void cancelNumber(String country, String msisdn) throws IOException, NexmoClientException { + CancelNumberResponse response = this.cancelNumber.execute(new CancelNumberRequest(country, msisdn)); + } + + /** + * Update the callbacks and/or application associations for a given Nexmo Virtual Number. + * + * @param request Details of the updates to be made to the number association. + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public void updateNumber(UpdateNumberRequest request) throws IOException, NexmoClientException { + this.updateNumber.execute(request); + } + + /** + * Link a given Nexmo Virtual Number to a Nexmo Application with the given ID. + * + * @param msisdn The Nexmo Virtual Number to be updated. + * @param country The country for the given msisdn. + * @param appId The ID for the Nexmo Application to be associated with the number. + * @throws IOException if an error occurs contacting the Nexmo API + * @throws NexmoClientException if an error is returned by the server. + */ + public void linkNumber(String msisdn, String country, String appId) throws IOException, NexmoClientException { + UpdateNumberRequest request = new UpdateNumberRequest(msisdn, country); + request.setVoiceCallbackType(UpdateNumberRequest.CallbackType.APP); + request.setVoiceCallbackValue(appId); + this.updateNumber(request); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/OwnedNumber.java b/src/main/java/com/nexmo/client/numbers/OwnedNumber.java new file mode 100644 index 000000000..81799cfae --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/OwnedNumber.java @@ -0,0 +1,91 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class OwnedNumber { + private String country; + private String msisdn; + private String moHttpUrl; + private String type; + private String[] features; + private String voiceCallbackType; + private String voiceCallbackValue; + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getMsisdn() { + return msisdn; + } + + public void setMsisdn(String msisdn) { + this.msisdn = msisdn; + } + + public String getMoHttpUrl() { + return moHttpUrl; + } + + public void setMoHttpUrl(String moHttpUrl) { + this.moHttpUrl = moHttpUrl; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String[] getFeatures() { + return features; + } + + public void setFeatures(String[] features) { + this.features = features; + } + + public String getVoiceCallbackType() { + return voiceCallbackType; + } + + public void setVoiceCallbackType(String voiceCallbackType) { + this.voiceCallbackType = voiceCallbackType; + } + + public String getVoiceCallbackValue() { + return voiceCallbackValue; + } + + public void setVoiceCallbackValue(String voiceCallbackValue) { + this.voiceCallbackValue = voiceCallbackValue; + } +} diff --git a/src/main/java/com/nexmo/client/numbers/SearchNumbersEndpoint.java b/src/main/java/com/nexmo/client/numbers/SearchNumbersEndpoint.java new file mode 100644 index 000000000..e4d6a370d --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/SearchNumbersEndpoint.java @@ -0,0 +1,73 @@ +/* + * 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.numbers; + + +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 org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * Internal class, representing the Nexmo API endpoint which can be used to search for available virtual numbers to buy. + *

+ * Use {@link NumbersClient#searchNumbers} instead of this class directly. + */ +public class SearchNumbersEndpoint extends AbstractMethod { + private static final String DEFAULT_URI = "https://rest.nexmo.com/number/search"; + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + private String uri = DEFAULT_URI; + + public SearchNumbersEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(SearchNumbersFilter request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get().setUri(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public SearchNumbersResponse parseResponse(HttpResponse response) throws IOException { + String json = new BasicResponseHandler().handleResponse(response); + return SearchNumbersResponse.fromJson(json); + } + + public SearchNumbersResponse searchNumbers(SearchNumbersFilter request) throws IOException, NexmoClientException { + return this.execute(request); + } +} diff --git a/src/main/java/com/nexmo/client/numbers/SearchNumbersFilter.java b/src/main/java/com/nexmo/client/numbers/SearchNumbersFilter.java new file mode 100644 index 000000000..9d77c5381 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/SearchNumbersFilter.java @@ -0,0 +1,119 @@ +/* + * 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.numbers; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.RequestBuilder; + +/** + * This class encapsulates a request to search for available Nexmo Virtual Numbers. + */ +public class SearchNumbersFilter { + private final String country; + + private String pattern; + private SearchPattern searchPattern; + private String[] features; + private Integer index; + private Integer size; + + /** + * Construct a request with the only required parameter, the country code. + * + * @param country A String containing a two-character country code. + */ + public SearchNumbersFilter(String country) { + this.country = country; + } + + public String getCountry() { + return country; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + + public String[] getFeatures() { + return features; + } + + public void setFeatures(String[] features) { + this.features = features; + } + + public Integer getIndex() { + return index; + } + + public void setIndex(Integer index) { + this.index = index; + } + + public Integer getSize() { + return size; + } + + /** + * Set the maximum number of matching results to be returned. + * + * @param size An Integer between 10 and 100 (inclusive) or null, to indicate that the default value should be used. + */ + public void setSize(Integer size) { + this.size = size; + } + + public SearchPattern getSearchPattern() { + return searchPattern; + } + + /** + * + * @param searchPattern + */ + public void setSearchPattern(SearchPattern searchPattern) { + this.searchPattern = searchPattern; + } + + public void addParams(RequestBuilder request) { + request.addParameter("country", country); + if (features != null && features.length > 0) { + request.addParameter("features", StringUtils.join(features, ",")); + } + if (index != null) { + request.addParameter("index", index.toString()); + } + if (size != null) { + request.addParameter("size", size.toString()); + } + if (pattern != null) { + request.addParameter("pattern", pattern); + } + if (searchPattern != null) { + request.addParameter("search_pattern", Integer.toString(searchPattern.getValue())); + } + } +} diff --git a/src/main/java/com/nexmo/client/numbers/SearchNumbersResponse.java b/src/main/java/com/nexmo/client/numbers/SearchNumbersResponse.java new file mode 100644 index 000000000..0a163536b --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/SearchNumbersResponse.java @@ -0,0 +1,61 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +/** + * Represents the response to a "searchNumbers" request from the Nexmo API. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class SearchNumbersResponse { + private int count = 0; + private AvailableNumber[] numbers = new AvailableNumber[]{}; + + /** + * Get the number of responses returned by the Nexmo API. + */ + public int getCount() { + return count; + } + + /** + * Obtain an array of matching numbers than are available to buy. + */ + public AvailableNumber[] getNumbers() { + return numbers; + } + + public static SearchNumbersResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, SearchNumbersResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce json from SearchNumbersResponse object.", jpe); + } + } + +} diff --git a/src/main/java/com/nexmo/client/numbers/SearchPattern.java b/src/main/java/com/nexmo/client/numbers/SearchPattern.java new file mode 100644 index 000000000..fb37ba28d --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/SearchPattern.java @@ -0,0 +1,41 @@ +/* + * 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.numbers; + +/** + * Provided to calls that match substrings, to indicate which part of the string should be considered a match. + */ +public enum SearchPattern { + STARTS_WITH(0), + ANYWHERE(1), + ENDS_WITH(2); + + private final int value; + + SearchPattern(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/src/main/java/com/nexmo/client/numbers/UpdateNumberEndpoint.java b/src/main/java/com/nexmo/client/numbers/UpdateNumberEndpoint.java new file mode 100644 index 000000000..6de493c17 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/UpdateNumberEndpoint.java @@ -0,0 +1,70 @@ +/* + * 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.numbers; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.NexmoMethodFailedException; +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 UpdateNumberEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/number/update"; + + private String uri = DEFAULT_URI; + + public UpdateNumberEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(UpdateNumberRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.post(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public Void parseResponse(HttpResponse httpResponse) throws IOException, NexmoClientException { + UpdateNumberResponse response = UpdateNumberResponse.fromJson(new BasicResponseHandler().handleResponse + (httpResponse)); + if (!response.getErrorCode().equals("200")) { + throw new NexmoMethodFailedException(response.getErrorCodeLabel()); + } + return null; + } +} diff --git a/src/main/java/com/nexmo/client/numbers/UpdateNumberRequest.java b/src/main/java/com/nexmo/client/numbers/UpdateNumberRequest.java new file mode 100644 index 000000000..4f5812e41 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/UpdateNumberRequest.java @@ -0,0 +1,115 @@ +/* + * 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.numbers; + +import org.apache.http.client.methods.RequestBuilder; + +public class UpdateNumberRequest { + private final String country; + private final String msisdn; + private String moHttpUrl; + private String moSmppSysType; + private CallbackType voiceCallbackType; + private String voiceCallbackValue; + private String voiceStatusCallback; + + public UpdateNumberRequest(String msisdn, String country) { + this.country = country; + this.msisdn = msisdn; + } + + public String getCountry() { + return country; + } + + public String getMsisdn() { + return msisdn; + } + + public String getMoHttpUrl() { + return moHttpUrl; + } + + public void setMoHttpUrl(String moHttpUrl) { + this.moHttpUrl = moHttpUrl; + } + + public String getMoSmppSysType() { + return moSmppSysType; + } + + public void setMoSmppSysType(String moSmppSysType) { + this.moSmppSysType = moSmppSysType; + } + + public CallbackType getVoiceCallbackType() { + return voiceCallbackType; + } + + public void setVoiceCallbackType(CallbackType voiceCallbackType) { + this.voiceCallbackType = voiceCallbackType; + } + + public String getVoiceCallbackValue() { + return voiceCallbackValue; + } + + public void setVoiceCallbackValue(String voiceCallbackValue) { + this.voiceCallbackValue = voiceCallbackValue; + } + + public String getVoiceStatusCallback() { + return voiceStatusCallback; + } + + public void setVoiceStatusCallback(String voiceStatusCallback) { + this.voiceStatusCallback = voiceStatusCallback; + } + + public void addParams(RequestBuilder request) { + request.addParameter("country", this.country).addParameter("msisdn", msisdn); + if (this.moHttpUrl != null) { + request.addParameter("moHttpUrl", moHttpUrl); + } + if (this.moSmppSysType != null) { + request.addParameter("moSmppSysType", moSmppSysType); + } + if (this.voiceCallbackType != null) { + request.addParameter("voiceCallbackType", voiceCallbackType.paramValue()); + } + if (this.voiceCallbackValue != null) { + request.addParameter("voiceCallbackValue", voiceCallbackValue); + } + if (this.voiceStatusCallback != null) { + request.addParameter("voiceStatusCallback", voiceStatusCallback); + } + + } + + public enum CallbackType { + SIP, TEL, VXML, APP; + + public String paramValue() { + return this.name().toString().toLowerCase(); + } + } +} diff --git a/src/main/java/com/nexmo/client/numbers/UpdateNumberResponse.java b/src/main/java/com/nexmo/client/numbers/UpdateNumberResponse.java new file mode 100644 index 000000000..451467126 --- /dev/null +++ b/src/main/java/com/nexmo/client/numbers/UpdateNumberResponse.java @@ -0,0 +1,54 @@ +/* + * 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.numbers; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class UpdateNumberResponse { + private String errorCode; + private String errorCodeLabel; + + @JsonProperty("error-code") + public String getErrorCode() { + return errorCode; + } + + @JsonProperty("error-code-label") + public String getErrorCodeLabel() { + return errorCodeLabel; + } + + public static UpdateNumberResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, UpdateNumberResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce UpdateNumberResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/sms/RejectedMessage.java b/src/main/java/com/nexmo/client/sms/RejectedMessage.java new file mode 100644 index 000000000..3f7de7991 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/RejectedMessage.java @@ -0,0 +1,65 @@ +/* + * 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.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Date; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class RejectedMessage { + private String accountId; + private String from; + private String to; + private Date dateReceived; + private Integer errorCode; + private String errorCodeLabel; + + @JsonProperty("account-id") + public String getAccountId() { + return accountId; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + @JsonProperty("date-received") + public Date getDateReceived() { + return dateReceived; + } + + @JsonProperty("error-code") + public Integer getErrorCode() { + return errorCode; + } + + @JsonProperty("error-code-label") + public String getErrorCodeLabel() { + return errorCodeLabel; + } +} diff --git a/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesEndpoint.java b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesEndpoint.java new file mode 100644 index 000000000..ccb578edb --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesEndpoint.java @@ -0,0 +1,64 @@ +/* + * 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 SearchRejectedMessagesEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/search/rejections"; + + private String uri = DEFAULT_URI; + + public SearchRejectedMessagesEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(SearchRejectedMessagesRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public SearchRejectedMessagesResponse parseResponse(HttpResponse response) throws IOException { + return SearchRejectedMessagesResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesRequest.java b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesRequest.java new file mode 100644 index 000000000..fdfe6c563 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesRequest.java @@ -0,0 +1,45 @@ +/* + * 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 org.apache.http.client.methods.RequestBuilder; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class SearchRejectedMessagesRequest { + private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + private final Date date; + private final String recipient; + + + public SearchRejectedMessagesRequest(Date date, String recipient) { + this.date = date; + this.recipient = recipient; + } + + public void addParams(RequestBuilder request) { + request.addParameter("date", this.dateFormat.format(this.date)) + .addParameter("to", this.recipient); + } +} diff --git a/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesResponse.java b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesResponse.java new file mode 100644 index 000000000..03c8b7677 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SearchRejectedMessagesResponse.java @@ -0,0 +1,53 @@ +/* + * 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.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; +import java.text.SimpleDateFormat; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class SearchRejectedMessagesResponse { + private int count; + private RejectedMessage[] items; + + public int getCount() { + return count; + } + + public RejectedMessage[] getItems() { + return items; + } + + public static SearchRejectedMessagesResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + return mapper.readValue(json, SearchRejectedMessagesResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce SearchRejectedMessagesResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/sms/SearchSmsRequest.java b/src/main/java/com/nexmo/client/sms/SearchSmsRequest.java new file mode 100644 index 000000000..9d2c7eabb --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SearchSmsRequest.java @@ -0,0 +1,28 @@ +/* + * 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 org.apache.http.client.methods.RequestBuilder; + +public interface SearchSmsRequest { + public void addParams(RequestBuilder request); +} diff --git a/src/main/java/com/nexmo/client/sms/SearchSmsResponse.java b/src/main/java/com/nexmo/client/sms/SearchSmsResponse.java new file mode 100644 index 000000000..c2e8af782 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SearchSmsResponse.java @@ -0,0 +1,53 @@ +/* + * 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.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; +import java.text.SimpleDateFormat; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class SearchSmsResponse { + private int count; + private SmsDetails[] items; + + public int getCount() { + return count; + } + + public SmsDetails[] getItems() { + return items; + } + + public static SearchSmsResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + return mapper.readValue(json, SearchSmsResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce SearchSmsResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/sms/SmsClient.java b/src/main/java/com/nexmo/client/sms/SmsClient.java index ef338f2e9..79a639030 100644 --- a/src/main/java/com/nexmo/client/sms/SmsClient.java +++ b/src/main/java/com/nexmo/client/sms/SmsClient.java @@ -29,20 +29,28 @@ import com.nexmo.client.sms.messages.Message; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; - /** +/** * A client for talking to the Nexmo Voice API. The standard way to obtain an instance of this class is to use * {@link NexmoClient#getSmsClient()}. */ public class SmsClient { private SendMessageEndpoint message; + private SmsSearchEndpoint search; + private SearchRejectedMessagesEndpoint rejected; /** * Create a new SmsClient. */ public SmsClient(HttpWrapper httpWrapper) { this.message = new SendMessageEndpoint(httpWrapper); + this.search = new SmsSearchEndpoint(httpWrapper); + this.rejected = new SearchRejectedMessagesEndpoint(httpWrapper); } /** @@ -65,4 +73,65 @@ public SmsSubmissionResult[] submitMessage(Message message) throws IOException, return this.message.execute(message); } + /** + * Search for completed SMS transactions. + *

+ * 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 { + return this.search.execute(request); + } + + /** + * Search for completed SMS transactions by ID + * + * @param id the first ID to look up + * @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 { + List idList = new ArrayList<>(ids.length + 1); + idList.add(id); + idList.addAll(Arrays.asList(ids)); + return this.searchMessages(new SmsIdSearchRequest(idList)); + } + + /** + * Search for completed SMS transactions by date and recipient MSISDN. + * + * @param date the date of the SMS message to be looked up + * @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 { + return this.searchMessages(new SmsDateSearchRequest(date, 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 { + return this.rejected.execute(request); + } + + /** + * Search for rejected SMS transactions by date and recipient MSISDN. + * + * @param date the date of the rejected SMS message to be looked up + * @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 { + return this.searchRejectedMessages(new SearchRejectedMessagesRequest(date, to)); + } } diff --git a/src/main/java/com/nexmo/client/sms/SmsDateSearchRequest.java b/src/main/java/com/nexmo/client/sms/SmsDateSearchRequest.java new file mode 100644 index 000000000..b54ac8454 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsDateSearchRequest.java @@ -0,0 +1,45 @@ +/* + * 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 org.apache.http.client.methods.RequestBuilder; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class SmsDateSearchRequest implements SearchSmsRequest { + private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + private final Date date; + private final String recipient; + + + public SmsDateSearchRequest(Date date, String recipient) { + this.date = date; + this.recipient = recipient; + } + + public void addParams(RequestBuilder request) { + request.addParameter("date", SmsDateSearchRequest.dateFormat.format(this.date)) + .addParameter("to", this.recipient); + } +} diff --git a/src/main/java/com/nexmo/client/sms/SmsDetails.java b/src/main/java/com/nexmo/client/sms/SmsDetails.java new file mode 100644 index 000000000..50b68961a --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsDetails.java @@ -0,0 +1,96 @@ +/* + * 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.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Date; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class SmsDetails { + private String messageId; + private String accountId; + private String network; + private String from; + private String to; + private String body; + private String price; + private Date dateReceived; + private String finalStatus; + private Date dateClosed; + private Integer latency; + private String type; + + @JsonProperty("message-id") + public String getMessageId() { + return messageId; + } + + @JsonProperty("account-id") + public String getAccountId() { + return accountId; + } + + public String getNetwork() { + return network; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public String getBody() { + return body; + } + + public String getPrice() { + return price; + } + + @JsonProperty("date-received") + public Date getDateReceived() { + return dateReceived; + } + + @JsonProperty("final-status") + public String getFinalStatus() { + return finalStatus; + } + + @JsonProperty("date-closed") + public Date getDateClosed() { + return dateClosed; + } + + public Integer getLatency() { + return latency; + } + + public String getType() { + return type; + } +} diff --git a/src/main/java/com/nexmo/client/sms/SmsIdSearchRequest.java b/src/main/java/com/nexmo/client/sms/SmsIdSearchRequest.java new file mode 100644 index 000000000..1c3fb8ec7 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsIdSearchRequest.java @@ -0,0 +1,51 @@ +/* + * 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 org.apache.http.client.methods.RequestBuilder; + +import java.util.ArrayList; +import java.util.List; + +public class SmsIdSearchRequest implements SearchSmsRequest { + private final List ids; + + public SmsIdSearchRequest(String id) { + this(new ArrayList(10)); + ids.add(id); + } + + public SmsIdSearchRequest(List ids) { + this.ids = new ArrayList<>(ids); + } + + public void addId(String id) { + this.ids.add(id); + } + + public void addParams(RequestBuilder request) { + for (String id : this.ids) { + request.addParameter("ids", id); + } + + } +} diff --git a/src/main/java/com/nexmo/client/sms/SmsSearchEndpoint.java b/src/main/java/com/nexmo/client/sms/SmsSearchEndpoint.java new file mode 100644 index 000000000..9ee3e6e03 --- /dev/null +++ b/src/main/java/com/nexmo/client/sms/SmsSearchEndpoint.java @@ -0,0 +1,64 @@ +/* + * 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 SmsSearchEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://rest.nexmo.com/search/messages"; + + private String uri = DEFAULT_URI; + + public SmsSearchEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(SearchSmsRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.get(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public SearchSmsResponse parseResponse(HttpResponse response) throws IOException { + return SearchSmsResponse.fromJson(new BasicResponseHandler().handleResponse(response)); + } +} diff --git a/src/main/java/com/nexmo/client/sms/messages/Message.java b/src/main/java/com/nexmo/client/sms/messages/Message.java index d11805ba3..20331e6dd 100644 --- a/src/main/java/com/nexmo/client/sms/messages/Message.java +++ b/src/main/java/com/nexmo/client/sms/messages/Message.java @@ -158,14 +158,25 @@ public void setCallbackUrl(String callbackUrl) { } /** - * @return boolean if set to true, then a delivery notification will be requested for this message delivery attempt. - * upon receiving notification of delivery or failure from the network, the nexmo platform will submit a notification to the url configured in your - * nexmo rest account that represents the outcome of this message. + * Get the value of the 'status-report-req' parameter. */ public boolean getStatusReportRequired() { return this.statusReportRequired; } + /** + * Set the value of the 'status-report-req' parameter. + * + * If set to 'true', Nexmo will call 'callbackUrl' with status updates about the delivery of this message. If this + * value is set to 'true', then 'callbackUrl' should also be set to a URL that is configured to receive these + * status updates. + * + * @param statusReportRequired 'true' if status reports are desired, 'false' otherwise. + */ + public void setStatusReportRequired(boolean statusReportRequired) { + this.statusReportRequired = statusReportRequired; + } + public void addParams(RequestBuilder request) { request.addParameter("from", getFrom()) .addParameter("to", getTo()) diff --git a/src/main/java/com/nexmo/client/verify/ControlRequest.java b/src/main/java/com/nexmo/client/verify/ControlRequest.java new file mode 100644 index 000000000..92d48e9a9 --- /dev/null +++ b/src/main/java/com/nexmo/client/verify/ControlRequest.java @@ -0,0 +1,49 @@ +/* + * 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.verify; + +import org.apache.http.client.methods.RequestBuilder; + +public class ControlRequest { + private final String requestId; + private final VerifyControlCommand command; + + public ControlRequest(String requestId, VerifyControlCommand command) { + this.requestId = requestId; + this.command = command; + } + + public String getRequestId() { + return requestId; + } + + public VerifyControlCommand getCommand() { + return command; + } + + public void addParams(RequestBuilder request) { + request + .addParameter("request_id", this.getRequestId()) + .addParameter("cmd", this.getCommand().toString()); + } + +} diff --git a/src/main/java/com/nexmo/client/verify/ControlResponse.java b/src/main/java/com/nexmo/client/verify/ControlResponse.java new file mode 100644 index 000000000..e4b3cd0e8 --- /dev/null +++ b/src/main/java/com/nexmo/client/verify/ControlResponse.java @@ -0,0 +1,70 @@ +/* + * 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.verify; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nexmo.client.NexmoUnexpectedException; + +import java.io.IOException; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ControlResponse { + private final String status; + private final VerifyControlCommand command; + private String errorText; + + @JsonCreator + public ControlResponse( + @JsonProperty("status") String status, + @JsonProperty("command") VerifyControlCommand command) { + this.status = status; + this.command = command; + this.errorText = null; + } + + @JsonProperty + public String getStatus() { + return status; + } + + @JsonProperty + public VerifyControlCommand getCommand() { + return command; + } + + @JsonProperty("error_text") + public String getErrorText(){ + return this.errorText; + } + + public static ControlResponse fromJson(String json) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(json, ControlResponse.class); + } catch (IOException jpe) { + throw new NexmoUnexpectedException("Failed to produce ControlResponse from json.", jpe); + } + } +} diff --git a/src/main/java/com/nexmo/client/verify/VerifyClient.java b/src/main/java/com/nexmo/client/verify/VerifyClient.java index 00dbdf6a0..2adeaad7d 100644 --- a/src/main/java/com/nexmo/client/verify/VerifyClient.java +++ b/src/main/java/com/nexmo/client/verify/VerifyClient.java @@ -27,6 +27,7 @@ import com.nexmo.client.NexmoClient; import com.nexmo.client.NexmoClientException; import com.nexmo.client.verify.endpoints.CheckEndpoint; +import com.nexmo.client.verify.endpoints.ControlEndpoint; import com.nexmo.client.verify.endpoints.SearchEndpoint; import com.nexmo.client.verify.endpoints.VerifyEndpoint; @@ -48,6 +49,7 @@ public class VerifyClient extends AbstractClient { private CheckEndpoint check; private VerifyEndpoint verify; private SearchEndpoint search; + private ControlEndpoint control; /** * Constructor. @@ -60,6 +62,7 @@ public VerifyClient(HttpWrapper httpWrapper) { this.check = new CheckEndpoint(httpWrapper); this.search = new SearchEndpoint(httpWrapper); this.verify = new VerifyEndpoint(httpWrapper); + this.control = new ControlEndpoint(httpWrapper); } /** @@ -185,6 +188,8 @@ public CheckResult check(final String requestId, } /** + * Search for a previous verification request. + * * @param requestId The requestId of a single Verify request to be looked up. * @return A SearchResult containing the details of the Verify request that was looked up, or null if no * record was found. @@ -196,6 +201,8 @@ public SearchResult search(String requestId) throws IOException, NexmoClientExce } /** + * Search for a previous verification request. + * * @param requestIds The requestIds of Verify requests to be looked up. * @return An array SearchResult for each record that was found. * @throws IOException if a network error occurred contacting the Nexmo Verify API. @@ -204,4 +211,26 @@ public SearchResult search(String requestId) throws IOException, NexmoClientExce public SearchResult[] search(String... requestIds) throws IOException, NexmoClientException { return search.search(requestIds); } + + /** + * Advance a current verification request to the next stage in the process. + * + * @param requestId The requestId of the ongoing verification request. + * @throws IOException If an IO error occurred while making the request. + * @throws NexmoClientException If the request failed for some reason. + */ + public void advanceVerification(String requestId) throws IOException, NexmoClientException { + control.execute(new ControlRequest(requestId, VerifyControlCommand.TRIGGER_NEXT_EVENT)); + } + + /** + * Cancel a current verification request. + * + * @param requestId The requestId of the ongoing verification request. + * @throws IOException If an IO error occurred while making the request. + * @throws NexmoClientException If the request failed for some reason. + */ + public void cancelVerification(String requestId) throws IOException, NexmoClientException { + control.execute(new ControlRequest(requestId, VerifyControlCommand.CANCEL)); + } } diff --git a/src/main/java/com/nexmo/client/verify/VerifyControlCommand.java b/src/main/java/com/nexmo/client/verify/VerifyControlCommand.java new file mode 100644 index 000000000..49ff029e7 --- /dev/null +++ b/src/main/java/com/nexmo/client/verify/VerifyControlCommand.java @@ -0,0 +1,41 @@ +/* + * 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.verify; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum VerifyControlCommand { + CANCEL, + TRIGGER_NEXT_EVENT; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } + + @JsonCreator + public static VerifyControlCommand fromString(String name) { + return VerifyControlCommand.valueOf(name.toUpperCase()); + } +} diff --git a/src/main/java/com/nexmo/client/verify/VerifyException.java b/src/main/java/com/nexmo/client/verify/VerifyException.java new file mode 100644 index 000000000..944698d50 --- /dev/null +++ b/src/main/java/com/nexmo/client/verify/VerifyException.java @@ -0,0 +1,43 @@ +/* + * 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.verify; + +import com.nexmo.client.NexmoClientException; + +public class VerifyException extends NexmoClientException { + private final String status; + private final String errorText; + + public VerifyException(String status, String errorText) { + super(String.format("Status %s: %s", status, errorText)); + this.status = status; + this.errorText = errorText; + } + + public String getStatus() { + return status; + } + + public String getErrorText() { + return errorText; + } +} diff --git a/src/main/java/com/nexmo/client/verify/endpoints/ControlEndpoint.java b/src/main/java/com/nexmo/client/verify/endpoints/ControlEndpoint.java new file mode 100644 index 000000000..e3994deb2 --- /dev/null +++ b/src/main/java/com/nexmo/client/verify/endpoints/ControlEndpoint.java @@ -0,0 +1,75 @@ +/* + * 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.verify.endpoints; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.verify.ControlRequest; +import com.nexmo.client.verify.ControlResponse; +import com.nexmo.client.verify.VerifyException; +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 ControlEndpoint extends AbstractMethod { + + private static final Class[] ALLOWED_AUTH_METHODS = new Class[]{TokenAuthMethod.class}; + + private static final String DEFAULT_URI = "https://api.nexmo.com/verify/control/json"; + + private String uri = DEFAULT_URI; + + public ControlEndpoint(HttpWrapper httpWrapper) { + super(httpWrapper); + } + + @Override + protected Class[] getAcceptableAuthMethods() { + return ALLOWED_AUTH_METHODS; + } + + @Override + public RequestBuilder makeRequest(ControlRequest request) throws NexmoClientException, + UnsupportedEncodingException { + RequestBuilder requestBuilder = RequestBuilder.post(uri); + request.addParams(requestBuilder); + return requestBuilder; + } + + @Override + public ControlResponse parseResponse(HttpResponse response) throws IOException, NexmoClientException { + ControlResponse controlResponse = ControlResponse.fromJson( + new BasicResponseHandler().handleResponse(response)); + if (!controlResponse.getStatus().equals("0")) { + throw new VerifyException( + controlResponse.getStatus(), + controlResponse.getErrorText()); + } + + return controlResponse; + } +} diff --git a/src/main/java/com/nexmo/client/verify/endpoints/SearchEndpoint.java b/src/main/java/com/nexmo/client/verify/endpoints/SearchEndpoint.java index a527688a8..8dbbbcf84 100644 --- a/src/main/java/com/nexmo/client/verify/endpoints/SearchEndpoint.java +++ b/src/main/java/com/nexmo/client/verify/endpoints/SearchEndpoint.java @@ -36,6 +36,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -99,7 +100,8 @@ public RequestBuilder makeRequest(SearchRequest request) throws NexmoClientExcep @Override public SearchResult[] parseResponse(HttpResponse response) throws IOException { - return parseSearchResponse(EntityUtils.toString(response.getEntity())); + String json = new BasicResponseHandler().handleResponse(response); + return parseSearchResponse(json); } public SearchResult search(String requestId) throws IOException, NexmoClientException { diff --git a/src/main/java/com/nexmo/client/verify/endpoints/VerifyCheckMethod.java b/src/main/java/com/nexmo/client/verify/endpoints/VerifyCheckMethod.java index 490ce34c5..fe85cdaf2 100644 --- a/src/main/java/com/nexmo/client/verify/endpoints/VerifyCheckMethod.java +++ b/src/main/java/com/nexmo/client/verify/endpoints/VerifyCheckMethod.java @@ -26,16 +26,16 @@ import com.nexmo.client.NexmoResponseParseException; import com.nexmo.client.auth.TokenAuthMethod; import com.nexmo.client.legacyutils.XmlParser; +import com.nexmo.client.legacyutils.XmlUtil; import com.nexmo.client.verify.BaseResult; -import com.nexmo.client.verify.CheckResult; import com.nexmo.client.verify.CheckRequest; +import com.nexmo.client.verify.CheckResult; import com.nexmo.client.voice.endpoints.AbstractMethod; -import com.nexmo.client.legacyutils.XmlUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.util.EntityUtils; +import org.apache.http.impl.client.BasicResponseHandler; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -79,7 +79,8 @@ public RequestBuilder makeRequest(CheckRequest request) throws NexmoClientExcept @Override public CheckResult parseResponse(HttpResponse response) throws IOException { - return parseCheckResponse(EntityUtils.toString(response.getEntity())); + String body = new BasicResponseHandler().handleResponse(response); + return parseCheckResponse(body); } private CheckResult parseCheckResponse(String response) throws NexmoResponseParseException { diff --git a/src/main/java/com/nexmo/client/voice/CallModifier.java b/src/main/java/com/nexmo/client/voice/CallModifier.java index f0e2c1719..65cf90011 100644 --- a/src/main/java/com/nexmo/client/voice/CallModifier.java +++ b/src/main/java/com/nexmo/client/voice/CallModifier.java @@ -26,28 +26,32 @@ import com.nexmo.client.NexmoUnexpectedException; - public class CallModifier { - private String uuid; - private ModifyCallPayload modifyCallPayload; + private final String uuid; + private final ModifyCallPayload modifyCallPayload; + + public CallModifier(String uuid, ModifyCallPayload modifyCallPayload) { + this.uuid = uuid; + this.modifyCallPayload = modifyCallPayload; + } - public CallModifier(String uuid, String action) { + public CallModifier(String uuid, ModifyCallAction action) { this.uuid = uuid; this.modifyCallPayload = new ModifyCallPayload(action); } + public static CallModifier transferCall(String uuid, String nccoUrl) { + return new CallModifier(uuid, new TransferCallPayload(nccoUrl)); + } + public String getUuid() { return uuid; } - public String getAction() { + public ModifyCallAction getAction() { return modifyCallPayload.getAction(); } - public void setAction(String action) { - this.modifyCallPayload.setAction(action); - } - public String toJson() { try { ObjectMapper mapper = new ObjectMapper(); @@ -56,4 +60,4 @@ public String toJson() { throw new NexmoUnexpectedException("Failed to produce json from CallModifier object.", jpe); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/CallStatus.java b/src/main/java/com/nexmo/client/voice/CallStatus.java index 5f556e6fc..26e0fd213 100644 --- a/src/main/java/com/nexmo/client/voice/CallStatus.java +++ b/src/main/java/com/nexmo/client/voice/CallStatus.java @@ -30,7 +30,11 @@ public enum CallStatus { ANSWERED, TIMEOUT, MACHINE, - COMPLETED; + COMPLETED, + FAILED, + REJECTED, + BUSY, + CANCELLED; @JsonValue @Override @@ -42,4 +46,4 @@ public String toString() { public static CallStatus fromString(String name) { return CallStatus.valueOf(name.toUpperCase()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/ModifyCallAction.java b/src/main/java/com/nexmo/client/voice/ModifyCallAction.java new file mode 100644 index 000000000..a99164826 --- /dev/null +++ b/src/main/java/com/nexmo/client/voice/ModifyCallAction.java @@ -0,0 +1,45 @@ +/* + * 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.voice; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ModifyCallAction { + HANGUP, + MUTE, + UNMUTE, + EARMUFF, + UNEARMUFF, + TRANSFER; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } + + @JsonCreator + public static ModifyCallAction fromString(String name) { + return ModifyCallAction.valueOf(name.toUpperCase()); + } +} diff --git a/src/main/java/com/nexmo/client/voice/ModifyCallPayload.java b/src/main/java/com/nexmo/client/voice/ModifyCallPayload.java index 02549ba84..392315d16 100644 --- a/src/main/java/com/nexmo/client/voice/ModifyCallPayload.java +++ b/src/main/java/com/nexmo/client/voice/ModifyCallPayload.java @@ -22,17 +22,18 @@ package com.nexmo.client.voice; public class ModifyCallPayload { - private String action; + private ModifyCallAction action; - public ModifyCallPayload(String action) { + public ModifyCallPayload(ModifyCallAction action) { this.action = action; } - public String getAction() { + public ModifyCallAction getAction() { return action; } - public void setAction(String action) { + public void setAction(ModifyCallAction action) { this.action = action; } -} \ No newline at end of file + +} diff --git a/src/main/java/com/nexmo/client/voice/ModifyCallResponse.java b/src/main/java/com/nexmo/client/voice/ModifyCallResponse.java index ccf796e89..175daf3e3 100644 --- a/src/main/java/com/nexmo/client/voice/ModifyCallResponse.java +++ b/src/main/java/com/nexmo/client/voice/ModifyCallResponse.java @@ -31,7 +31,7 @@ /** * Response if a {@link Call} was successfully modified. *

- * This would be returned by {@link VoiceClient#modifyCall(String, String)} + * This would be returned by {@link VoiceClient#modifyCall(String, ModifyCallAction)} */ @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/src/main/java/com/nexmo/client/voice/TransferCallPayload.java b/src/main/java/com/nexmo/client/voice/TransferCallPayload.java new file mode 100644 index 000000000..fae3e7300 --- /dev/null +++ b/src/main/java/com/nexmo/client/voice/TransferCallPayload.java @@ -0,0 +1,38 @@ +/* + * 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.voice; + +/** + * Extension of ModifyCallPayload which adds an NCCO destination to the serialized form. + */ +public class TransferCallPayload extends ModifyCallPayload { + private final String nccoUrl; + + public TransferCallPayload(String nccoUrl) { + super(ModifyCallAction.TRANSFER); + this.nccoUrl = nccoUrl; + } + + public TransferDestination getDestination() { + return new TransferDestination(TransferDestination.Type.NCCO, this.nccoUrl); + } +} diff --git a/src/main/java/com/nexmo/client/voice/TransferDestination.java b/src/main/java/com/nexmo/client/voice/TransferDestination.java new file mode 100644 index 000000000..6d50cde4a --- /dev/null +++ b/src/main/java/com/nexmo/client/voice/TransferDestination.java @@ -0,0 +1,56 @@ +/* + * 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.voice; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + +public class TransferDestination { + private final Type type; + private final String[] urls; + + public TransferDestination(Type type, String url) { + this.type = type; + this.urls = new String[]{url}; + } + + @JsonProperty("type") + public Type getType() { + return type; + } + + @JsonProperty("url") + public String[] getUrls() { + return urls; + } + + enum Type { + NCCO; + + @JsonValue + @Override + public String toString() { + return name().toLowerCase(); + } + } +} diff --git a/src/main/java/com/nexmo/client/voice/VoiceClient.java b/src/main/java/com/nexmo/client/voice/VoiceClient.java index 357b917de..e3322ad41 100644 --- a/src/main/java/com/nexmo/client/voice/VoiceClient.java +++ b/src/main/java/com/nexmo/client/voice/VoiceClient.java @@ -125,20 +125,55 @@ public DtmfResponse sendDtmf(String uuid, String digits) throws IOException, Nex } /** - * Hang up a call. + * Modify an ongoing call. *

- * In future, further operations will be possible. At the moment, the only valid value for action is - * hangup. + * This method modifies an ongoing call, identified by "uuid". Modifications to the call can be one of: + *

    + *
  • Terminate the call (hangup) + *
  • Mute a call leg (mute) + *
  • Unmute a call leg (unmute) + *
  • Earmuff a call leg (earmuff) + *
  • Unearmuff a call leg (unearmuff) + *
* - * @param uuid (required) The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. + * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. * This value can be obtained with {@link CallEvent#getUuid()} - * @param action The word "hangup" - * @return A CallInfo object, representing the response from the Nexmo Voice API. + * @param action One of: "hangup", "mute", "unmute", "earmuff", "unearmuff" + * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. + * @throws IOException if a network error occurred contacting the Nexmo Voice API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public ModifyCallResponse modifyCall(String uuid, ModifyCallAction action) throws IOException, NexmoClientException { + return this.modifyCall(new CallModifier(uuid, action)); + } + + /** + * Modify an ongoing call using a CallModifier object. + *

+ * In most cases, you will want to use {@link #modifyCall(String, ModifyCallAction)} or {@link #transferCall(String, String)} + * instead of this method. + * + * @param modifier A CallModifier describing the modification to be made. + * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. + * @throws IOException if a network error occurred contacting the Nexmo Voice API. + * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. + */ + public ModifyCallResponse modifyCall(CallModifier modifier) throws IOException, NexmoClientException { + return calls.put(modifier); + } + + /** + * Transfer a call to a different NCCO endpoint. + * + * @param uuid The UUID of the call, obtained from the object returned by {@link #createCall(Call)}. This value can + * be obtained with {@link CallEvent#getUuid()} + * @param nccoUrl The URL of the NCCO endpoint the call should be transferred to + * @return A ModifyCallResponse object, representing the response from the Nexmo Voice API. * @throws IOException if a network error occurred contacting the Nexmo Voice API. * @throws NexmoClientException if there was a problem with the Nexmo request or response objects. */ - public ModifyCallResponse modifyCall(String uuid, String action) throws IOException, NexmoClientException { - return calls.put(uuid, action); + public ModifyCallResponse transferCall(String uuid, String nccoUrl) throws IOException, NexmoClientException { + return this.modifyCall(CallModifier.transferCall(uuid, nccoUrl)); } /** diff --git a/src/main/java/com/nexmo/client/voice/endpoints/AbstractMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/AbstractMethod.java index 7c57b635a..f42481e83 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/AbstractMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/AbstractMethod.java @@ -23,6 +23,7 @@ import com.nexmo.client.HttpWrapper; import com.nexmo.client.NexmoClientException; +import com.nexmo.client.NexmoMethodFailedException; import com.nexmo.client.NexmoUnexpectedException; import com.nexmo.client.auth.AuthMethod; import org.apache.commons.logging.Log; @@ -103,7 +104,6 @@ public ResultT execute(RequestT request) throws IOException, NexmoClientExceptio LOG.debug(EntityUtils.toString(enclosingRequest.getEntity())); } HttpResponse response = this.httpWrapper.getHttpClient().execute(httpRequest); - LOG.debug("Response: " + response.getStatusLine()); return parseResponse(response); } catch (UnsupportedEncodingException uee) { throw new NexmoUnexpectedException("UTF-8 encoding is not supported by this JVM.", uee); @@ -166,5 +166,5 @@ public abstract RequestBuilder makeRequest(RequestT request) * @return A ResultT type representing the result of the REST call * @throws IOException if a problem occurs parsing the response */ - public abstract ResultT parseResponse(HttpResponse response) throws IOException; + public abstract ResultT parseResponse(HttpResponse response) throws IOException, NexmoClientException; } diff --git a/src/main/java/com/nexmo/client/voice/endpoints/CallsEndpoint.java b/src/main/java/com/nexmo/client/voice/endpoints/CallsEndpoint.java index c2f26b0f1..778e419aa 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/CallsEndpoint.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/CallsEndpoint.java @@ -88,19 +88,15 @@ public CallInfo get(String uuid) throws IOException, NexmoClientException { return this.readCall.execute(uuid); } - /** * Modify an ongoing call. - *

- * Currently this method only supports the "hangup" action. * - * @param uuid The uuid of the CallInfo object to be modified - * @param action The word "hangup" + * @param modifier A CallModifier describing the modification to make to the call. * @return A ModifyCallResponse object describing the state of the call that was modified * @throws IOException if an error occurs communicating with the Nexmo API * @throws NexmoClientException if an error occurs constructing the Nexmo API request or response */ - public ModifyCallResponse put(String uuid, String action) throws IOException, NexmoClientException { - return this.modifyCall.execute(new CallModifier(uuid, action)); + public ModifyCallResponse put(CallModifier modifier) throws IOException, NexmoClientException { + return this.modifyCall.execute(modifier); } } diff --git a/src/main/java/com/nexmo/client/voice/endpoints/CreateCallMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/CreateCallMethod.java index f8e4dc51f..8578ed2be 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/CreateCallMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/CreateCallMethod.java @@ -31,6 +31,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -62,12 +63,11 @@ protected Class[] getAcceptableAuthMethods() { @Override public CallEvent parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return CallEvent.fromJson(json); } public void setUri(String uri) { this.uri = uri; } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/endpoints/ListCallsMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/ListCallsMethod.java index f801ffbb1..aeba5522f 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/ListCallsMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/ListCallsMethod.java @@ -34,6 +34,7 @@ import org.apache.http.NameValuePair; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -76,8 +77,7 @@ public RequestBuilder makeRequest(CallsFilter filter) throws NexmoClientExceptio @Override public CallInfoPage parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.debug("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return CallInfoPage.fromJson(json); } @@ -88,4 +88,4 @@ public void setUri(String uri) { public String getUri() { return this.uri; } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/endpoints/ModifyCallMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/ModifyCallMethod.java index a99b8c548..8079abf98 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/ModifyCallMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/ModifyCallMethod.java @@ -31,6 +31,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -64,8 +65,7 @@ public RequestBuilder makeRequest(CallModifier request) throws NexmoClientExcept @Override public ModifyCallResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return ModifyCallResponse.fromJson(json); } diff --git a/src/main/java/com/nexmo/client/voice/endpoints/ReadCallMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/ReadCallMethod.java index 7f87558e9..523b0c000 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/ReadCallMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/ReadCallMethod.java @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -57,8 +58,7 @@ public RequestBuilder makeRequest(String callId) { @Override public CallInfo parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return CallInfo.fromJson(json); } @@ -69,4 +69,4 @@ public void setBaseUri(String baseUri) { public String getBaseUri() { return baseUri; } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/endpoints/SendDtmfMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/SendDtmfMethod.java index 501748565..b142ed26e 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/SendDtmfMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/SendDtmfMethod.java @@ -31,6 +31,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -62,12 +63,11 @@ public RequestBuilder makeRequest(DtmfRequest request) throws NexmoClientExcepti @Override public DtmfResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return DtmfResponse.fromJson(json); } public void setUri(String uri) { this.uri = uri; } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/endpoints/StartStreamMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/StartStreamMethod.java index e0fd7515c..1ee4ec4c4 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/StartStreamMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/StartStreamMethod.java @@ -31,6 +31,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -62,12 +63,11 @@ public RequestBuilder makeRequest(StreamRequest request) throws NexmoClientExcep @Override public StreamResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return StreamResponse.fromJson(json); } public void setUri(String uri) { this.uri = uri; } -} \ No newline at end of file +} diff --git a/src/main/java/com/nexmo/client/voice/endpoints/StartTalkMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/StartTalkMethod.java index ad4ef3f25..b51d6a4bf 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/StartTalkMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/StartTalkMethod.java @@ -31,6 +31,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -62,8 +63,7 @@ public RequestBuilder makeRequest(TalkRequest request) throws NexmoClientExcepti @Override public TalkResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return TalkResponse.fromJson(json); } diff --git a/src/main/java/com/nexmo/client/voice/endpoints/StopStreamMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/StopStreamMethod.java index df13d89b6..897515ae0 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/StopStreamMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/StopStreamMethod.java @@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -59,8 +60,7 @@ public RequestBuilder makeRequest(String uuid) throws NexmoClientException, Unsu @Override public StreamResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return StreamResponse.fromJson(json); } diff --git a/src/main/java/com/nexmo/client/voice/endpoints/StopTalkMethod.java b/src/main/java/com/nexmo/client/voice/endpoints/StopTalkMethod.java index dc39b81a7..2b7d03ddf 100644 --- a/src/main/java/com/nexmo/client/voice/endpoints/StopTalkMethod.java +++ b/src/main/java/com/nexmo/client/voice/endpoints/StopTalkMethod.java @@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.util.EntityUtils; import java.io.IOException; @@ -59,12 +60,11 @@ public RequestBuilder makeRequest(String uuid) throws NexmoClientException, Unsu @Override public TalkResponse parseResponse(HttpResponse response) throws IOException { - String json = EntityUtils.toString(response.getEntity()); - LOG.info("Received: " + json); + String json = new BasicResponseHandler().handleResponse(response); return TalkResponse.fromJson(json); } public void setUri(String uri) { this.uri = uri; } -} \ No newline at end of file +} diff --git a/src/test/java/com/nexmo/client/TestUtils.java b/src/test/java/com/nexmo/client/TestUtils.java index 773945773..1699a0208 100644 --- a/src/test/java/com/nexmo/client/TestUtils.java +++ b/src/test/java/com/nexmo/client/TestUtils.java @@ -21,9 +21,11 @@ */ package com.nexmo.client; +import com.nexmo.client.voice.endpoints.AbstractMethod; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpResponseException; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; @@ -33,10 +35,13 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import static junit.framework.Assert.fail; + public class TestUtils { public byte[] loadKey(String path) throws IOException { int len; @@ -64,9 +69,26 @@ public static Map makeParameterMap(List params) { return result; } + /** + * Used in cases where the same url parameter is repeated, returns a map where the values are Lists of Strings, + * rather than just an individual String + */ + public static Map> makeFullParameterMap(List params) { + Map> result = new HashMap<>(); + for (NameValuePair param : params) { + List values = result.get(param.getName()); + if (values == null) { + values = new ArrayList<>(1); + result.put(param.getName(), values); + } + values.add(param.getValue()); + } + return result; + } + public static HttpResponse makeJsonHttpResponse(int statusCode, String json) { HttpResponse stubResponse = new BasicHttpResponse( - new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), 200, "OK") + new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), statusCode, "OK") ); InputStream jsonStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); BasicHttpEntity entity = new BasicHttpEntity(); @@ -75,4 +97,13 @@ public static HttpResponse makeJsonHttpResponse(int statusCode, String json) { return stubResponse; } + + public static void test429(AbstractMethod methodUnderTest) throws Exception { + try { + methodUnderTest.parseResponse(TestUtils.makeJsonHttpResponse(429, "Don't know what this is")); + fail("A 429 response should raise a HttpResponseException"); + } catch (HttpResponseException e) { + // This is expected + } + } } diff --git a/src/test/java/com/nexmo/client/account/AccountClientTest.java b/src/test/java/com/nexmo/client/account/AccountClientTest.java new file mode 100644 index 000000000..5ad0aa2b4 --- /dev/null +++ b/src/test/java/com/nexmo/client/account/AccountClientTest.java @@ -0,0 +1,49 @@ +/* + * 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.account; + +import junit.framework.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.mockito.Mockito.*; + +public class AccountClientTest { + private AccountClient client; + private BalanceResponse sentinel; + + @Before + public void setUp() throws Exception { + client = new AccountClient(null); + client.balance = mock(BalanceEndpoint.class); + sentinel = new BalanceResponse(1.1, true); + when(client.balance.execute()).thenReturn(sentinel); + } + + @Test + public void testGetBalance() throws Exception { + BalanceResponse response = client.getBalance(); + verify(client.balance).execute(); + Assert.assertEquals(sentinel, response); + } + +} diff --git a/src/test/java/com/nexmo/client/account/BalanceEndpointTest.java b/src/test/java/com/nexmo/client/account/BalanceEndpointTest.java new file mode 100644 index 000000000..54598b48c --- /dev/null +++ b/src/test/java/com/nexmo/client/account/BalanceEndpointTest.java @@ -0,0 +1,91 @@ +/* + * 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.account; + +import com.nexmo.client.NexmoClientException; +import com.nexmo.client.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class BalanceEndpointTest { + private BalanceEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new BalanceEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(null); + assertEquals("GET", builder.getMethod()); + assertEquals("https://rest.nexmo.com/account/get-balance", builder.build().getURI().toString()); + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(0, params.size()); + + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"value\": 3.14159,\n" + + " \"autoReload\": false\n" + + "}}"); + BalanceResponse response = this.endpoint.parseResponse(stub); + assertEquals(3.14159, response.getValue(), 0.00001); + assertEquals(false, response.isAutoReload()); + } + + private class StubbedBalanceEndpoint extends BalanceEndpoint { + public StubbedBalanceEndpoint() { + super(null); + } + + @Override + public BalanceResponse execute() throws IOException, NexmoClientException { + return new BalanceResponse(1.5, true); + } + } + + @Test + public void testExecute() throws Exception { + BalanceEndpoint endpoint = new StubbedBalanceEndpoint(); + BalanceResponse response = endpoint.execute(); + assertEquals(response.getValue(), 1.5, 0.0001); + assertEquals(response.isAutoReload(), true); + } +} diff --git a/src/test/java/com/nexmo/client/account/BalanceResponseTest.java b/src/test/java/com/nexmo/client/account/BalanceResponseTest.java new file mode 100644 index 000000000..7259545b1 --- /dev/null +++ b/src/test/java/com/nexmo/client/account/BalanceResponseTest.java @@ -0,0 +1,39 @@ +/* + * 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.account; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class BalanceResponseTest { + @Test + public void testJsonError() throws Exception { + try { + BalanceResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} diff --git a/src/test/java/com/nexmo/client/applications/ApplicationClientTest.java b/src/test/java/com/nexmo/client/applications/ApplicationClientTest.java new file mode 100644 index 000000000..eb0a33ce2 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/ApplicationClientTest.java @@ -0,0 +1,231 @@ +/* + * 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.applications; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.auth.AuthCollection; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; +import org.junit.Test; + +import java.io.ByteArrayInputStream; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +public class ApplicationClientTest { + private static HttpWrapper stubHttpWrapper(int statusCode, String content) throws Exception { + HttpClient client = mock(HttpClient.class); + + HttpResponse response = mock(HttpResponse.class); + StatusLine sl = mock(StatusLine.class); + HttpEntity entity = mock(HttpEntity.class); + + when(client.execute(any(HttpUriRequest.class))).thenReturn(response); + when(entity.getContent()).thenReturn(new ByteArrayInputStream(content.getBytes("UTF-8"))); + when(sl.getStatusCode()).thenReturn(statusCode); + when(response.getStatusLine()).thenReturn(sl); + when(response.getEntity()).thenReturn(entity); + + AuthCollection authCollection = new AuthCollection(); + authCollection.add(new TokenAuthMethod("api-key", "api-secret")); + + HttpWrapper wrapper = new HttpWrapper(authCollection); + wrapper.setHttpClient(client); + + return wrapper; + } + + @Test + public void testCreateApplication() throws Exception { + ApplicationClient client = new ApplicationClient(stubHttpWrapper(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\",\n" + + " \"private_key\": \"PRIVATE_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}")); + ApplicationDetails response = client.createApplication( + new CreateApplicationRequest( + "My Application", + "https://example.com/answer", + "https://example.com/event")); + assertEquals("My Application", response.getName()); + } + + + @Test + public void testUpdateApplication() throws Exception { + ApplicationClient client = new ApplicationClient(stubHttpWrapper(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\",\n" + + " \"private_key\": \"PRIVATE_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}")); + ApplicationDetails response = client.updateApplication( + new UpdateApplicationRequest( + "app-id", + "My Application", + "https://example.com/answer", + "https://example.com/event")); + assertEquals("My Application", response.getName()); + } + + @Test + public void testGetApplication() throws Exception { + ApplicationClient client = new ApplicationClient(stubHttpWrapper(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\",\n" + + " \"private_key\": \"PRIVATE_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}")); + ApplicationDetails response = client.getApplication("app-id"); + assertEquals("My Application", response.getName()); + } + + @Test + public void testListApplications() throws Exception { + ApplicationClient client = new ApplicationClient(stubHttpWrapper(200, "{\n" + + " \"count\": 1,\n" + + " \"page_size\": 10,\n" + + " \"page_index\": 3,\n" + + " \"_embedded\": {\n" + + " \"applications\": [\n" + + " {\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=1\"\n" + + " },\n" + + " \"first\": {\n" + + " \"href\": \"/v1/applications?page_size=10\"\n" + + " },\n" + + " \"last\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=5\"\n" + + " },\n" + + " \"next\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=2\"\n" + + " }\n" + + " }\n" + + "}")); + ListApplicationsResponse response = client.listApplications(new ListApplicationsRequest()); + assertEquals("My Application", response.iterator().next().getName()); + } + + @Test + public void testDeleteApplication() throws Exception { + ApplicationClient client = new ApplicationClient(stubHttpWrapper(204, "")); + client.deleteApplication("app-id"); + } +} diff --git a/src/test/java/com/nexmo/client/applications/ApplicationTypeTest.java b/src/test/java/com/nexmo/client/applications/ApplicationTypeTest.java new file mode 100644 index 000000000..23b650799 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/ApplicationTypeTest.java @@ -0,0 +1,38 @@ +package com.nexmo.client.applications;/* + * 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. + */ + +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class ApplicationTypeTest { + @Test + public void testValueOf() throws Exception { + assertEquals(ApplicationType.VOICE, ApplicationType.valueOf("VOICE")); + } + + @Test + public void testValues() throws Exception { + assertArrayEquals(new ApplicationType[]{ApplicationType.VOICE}, ApplicationType.values()); + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/ApplicationDetailsTest.java b/src/test/java/com/nexmo/client/applications/endpoints/ApplicationDetailsTest.java new file mode 100644 index 000000000..54d968ec9 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/ApplicationDetailsTest.java @@ -0,0 +1,40 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.NexmoUnexpectedException; +import com.nexmo.client.applications.ApplicationDetails; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class ApplicationDetailsTest { + @Test + public void testJsonError() throws Exception { + try { + ApplicationDetails.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/CreateApplicationMethodTest.java b/src/test/java/com/nexmo/client/applications/endpoints/CreateApplicationMethodTest.java new file mode 100644 index 000000000..f89debd50 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/CreateApplicationMethodTest.java @@ -0,0 +1,140 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.applications.ApplicationDetails; +import com.nexmo.client.applications.ApplicationKeys; +import com.nexmo.client.applications.CreateApplicationRequest; +import com.nexmo.client.applications.WebHook; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.*; + +public class CreateApplicationMethodTest { + private CreateApplicationMethod endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new CreateApplicationMethod(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new CreateApplicationRequest( + "app name", "https://example.com/answer", "https://example.com/event" + )); + assertEquals("POST", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("app name", params.get("name")); + assertEquals("https://example.com/event", params.get("event_url")); + assertEquals("https://example.com/answer", params.get("answer_url")); + assertNull(params.get("event_method")); + assertNull(params.get("answer_method")); + } + + @Test + public void testMakeRequestWithOptionalParams() throws Exception { + CreateApplicationRequest create = new CreateApplicationRequest( + "app name", "https://example.com/answer", "https://example.com/event" + ); + create.setAnswerMethod("PUT"); + create.setEventMethod("DELETE"); + RequestBuilder builder = this.endpoint.makeRequest(create); + assertEquals("POST", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("app name", params.get("name")); + assertEquals("https://example.com/event", params.get("event_url")); + assertEquals("https://example.com/answer", params.get("answer_url")); + assertEquals("PUT", params.get("answer_method")); + assertEquals("DELETE", params.get("event_method")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\",\n" + + " \"private_key\": \"PRIVATE_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}"); + ApplicationDetails response = this.endpoint.parseResponse(stub); + assertEquals("aaaaaaaa-bbbb-cccc-dddd-0123456789ab", response.getId()); + assertEquals("My Application", response.getName()); + + assertNotNull(response.getVoiceApplicationDetails()); + assertNotNull(response.getVoiceApplicationDetails().getWebHooks()); + + WebHook answer = response.getVoiceApplicationDetails().getWebHooks()[0]; + assertEquals("answer_url", answer.getEndpointType()); + assertEquals("https://example.com/answer", answer.getEndpointUrl()); + assertEquals("GET", answer.getHttpMethod()); + + WebHook event = response.getVoiceApplicationDetails().getWebHooks()[1]; + assertEquals("event_url", event.getEndpointType()); + assertEquals("https://example.com/event", event.getEndpointUrl()); + assertEquals("POST", event.getHttpMethod()); + + assertNotNull(response.getKeys()); + ApplicationKeys keys = response.getKeys(); + + assertEquals("PUBLIC_KEY", keys.getPublicKey()); + assertEquals("PRIVATE_KEY", keys.getPrivateKey()); + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethodTest.java b/src/test/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethodTest.java new file mode 100644 index 000000000..33bac31f0 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/DeleteApplicationMethodTest.java @@ -0,0 +1,65 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class DeleteApplicationMethodTest { + private DeleteApplicationMethod endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new DeleteApplicationMethod(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest("dummy-application-uuid"); + assertEquals("DELETE", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications/dummy-application-uuid", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(0, params.size()); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(204, ""); + this.endpoint.parseResponse(stub); + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/GetApplicationEndpointTest.java b/src/test/java/com/nexmo/client/applications/endpoints/GetApplicationEndpointTest.java new file mode 100644 index 000000000..4eb515bf4 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/GetApplicationEndpointTest.java @@ -0,0 +1,114 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.applications.ApplicationDetails; +import com.nexmo.client.applications.ApplicationKeys; +import com.nexmo.client.applications.WebHook; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.*; + +public class GetApplicationEndpointTest { + private GetApplicationEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new GetApplicationEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest("app-id"); + assertEquals("GET", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications/app-id", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(0, params.size()); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\",\n" + + " \"private_key\": \"PRIVATE_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}"); + ApplicationDetails response = this.endpoint.parseResponse(stub); + assertEquals("aaaaaaaa-bbbb-cccc-dddd-0123456789ab", response.getId()); + assertEquals("My Application", response.getName()); + + assertNotNull(response.getVoiceApplicationDetails()); + assertNotNull(response.getVoiceApplicationDetails().getWebHooks()); + + WebHook answer = response.getVoiceApplicationDetails().getWebHooks()[0]; + assertEquals("answer_url", answer.getEndpointType()); + assertEquals("https://example.com/answer", answer.getEndpointUrl()); + assertEquals("GET", answer.getHttpMethod()); + + WebHook event = response.getVoiceApplicationDetails().getWebHooks()[1]; + assertEquals("event_url", event.getEndpointType()); + assertEquals("https://example.com/event", event.getEndpointUrl()); + assertEquals("POST", event.getHttpMethod()); + + assertNotNull(response.getKeys()); + ApplicationKeys keys = response.getKeys(); + + assertEquals("PUBLIC_KEY", keys.getPublicKey()); + assertEquals("PRIVATE_KEY", keys.getPrivateKey()); + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpointTest.java b/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpointTest.java new file mode 100644 index 000000000..aa51a95dd --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsEndpointTest.java @@ -0,0 +1,158 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.applications.*; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.*; + +public class ListApplicationsEndpointTest { + private ListApplicationsEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new ListApplicationsEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new ListApplicationsRequest()); + assertEquals("GET", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(0, params.size()); + } + + @Test + public void testMakeRequestWithParams() throws Exception { + ListApplicationsRequest request = new ListApplicationsRequest(); + request.setPageIndex(32); + request.setPageSize(40); + + RequestBuilder builder = this.endpoint.makeRequest(request); + assertEquals("GET", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications?page_size=40&page_index=32", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("32", params.get("page_index")); + assertEquals("40", params.get("page_size")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"count\": 1,\n" + + " \"page_size\": 10,\n" + + " \"page_index\": 3,\n" + + " \"_embedded\": {\n" + + " \"applications\": [\n" + + " {\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=1\"\n" + + " },\n" + + " \"first\": {\n" + + " \"href\": \"/v1/applications?page_size=10\"\n" + + " },\n" + + " \"last\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=5\"\n" + + " },\n" + + " \"next\": {\n" + + " \"href\": \"/v1/applications?page_size=10&page_index=2\"\n" + + " }\n" + + " }\n" + + "}"); + ListApplicationsResponse response = this.endpoint.parseResponse(stub); + assertEquals(1, response.getCount()); + assertEquals(10, response.getPageSize()); + assertEquals(3, response.getPageIndex()); + + ApplicationDetails app = response.iterator().next(); + assertNotNull(app); + + assertEquals("aaaaaaaa-bbbb-cccc-dddd-0123456789ab", app.getId()); + assertEquals("My Application", app.getName()); + + assertNotNull(app.getVoiceApplicationDetails()); + assertNotNull(app.getVoiceApplicationDetails().getWebHooks()); + + WebHook event = app.getVoiceApplicationDetails().getWebHooks()[0]; + assertEquals("event_url", event.getEndpointType()); + assertEquals("https://example.com/event", event.getEndpointUrl()); + assertEquals("POST", event.getHttpMethod()); + + WebHook answer = app.getVoiceApplicationDetails().getWebHooks()[1]; + assertEquals("answer_url", answer.getEndpointType()); + assertEquals("https://example.com/answer", answer.getEndpointUrl()); + assertEquals("GET", answer.getHttpMethod()); + + assertNotNull(app.getKeys()); + ApplicationKeys keys = app.getKeys(); + + assertEquals("PUBLIC_KEY", keys.getPublicKey()); + assertNull(keys.getPrivateKey()); + + assertEquals(response.getEmbedded().getApplicationDetails()[0], app); + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsResponseTest.java b/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsResponseTest.java new file mode 100644 index 000000000..9b0e2bfe6 --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/ListApplicationsResponseTest.java @@ -0,0 +1,40 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.NexmoUnexpectedException; +import com.nexmo.client.applications.ListApplicationsResponse; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class ListApplicationsResponseTest { + @Test + public void testJsonError() throws Exception { + try { + ListApplicationsResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} diff --git a/src/test/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethodTest.java b/src/test/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethodTest.java new file mode 100644 index 000000000..cf09c22bf --- /dev/null +++ b/src/test/java/com/nexmo/client/applications/endpoints/UpdateApplicationMethodTest.java @@ -0,0 +1,144 @@ +/* + * 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.applications.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.applications.ApplicationDetails; +import com.nexmo.client.applications.ApplicationKeys; +import com.nexmo.client.applications.UpdateApplicationRequest; +import com.nexmo.client.applications.WebHook; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.*; + +public class UpdateApplicationMethodTest { + private UpdateApplicationMethod endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new UpdateApplicationMethod(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequestWithOptionalParams() throws Exception { + UpdateApplicationRequest update = new UpdateApplicationRequest( + "app-id", "app name", "https://example.com/answer", "https://example.com/event" + ); + update.setAnswerMethod("PUT"); + update.setEventMethod("DELETE"); + + RequestBuilder builder = this.endpoint.makeRequest(update); + assertEquals("PUT", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications/app-id", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("app name", params.get("name")); + assertEquals("https://example.com/event", params.get("event_url")); + assertEquals("https://example.com/answer", params.get("answer_url")); + assertEquals("PUT", params.get("answer_method")); + assertEquals("DELETE", params.get("event_method")); + assertNull(params.get("app_id")); + } + + @Test + public void testMakeRequest() throws Exception { + UpdateApplicationRequest update = new UpdateApplicationRequest( + "app-id", "app name", "https://example.com/answer", "https://example.com/event" + ); + + RequestBuilder builder = this.endpoint.makeRequest(update); + assertEquals("PUT", builder.getMethod()); + assertEquals("https://api.nexmo.com/v1/applications/app-id", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("app name", params.get("name")); + assertEquals("https://example.com/event", params.get("event_url")); + assertEquals("https://example.com/answer", params.get("answer_url")); + assertNull(params.get("answer_method")); + assertNull(params.get("event_method")); + assertNull(params.get("app_id")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"id\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\",\n" + + " \"name\": \"My Application\",\n" + + " \"voice\": {\n" + + " \"webhooks\": [\n" + + " {\n" + + " \"endpoint_type\": \"answer_url\",\n" + + " \"endpoint\": \"https://example.com/answer\",\n" + + " \"http_method\": \"GET\"\n" + + " },\n" + + " {\n" + + " \"endpoint_type\": \"event_url\",\n" + + " \"endpoint\": \"https://example.com/event\",\n" + + " \"http_method\": \"POST\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"keys\": {\n" + + " \"public_key\": \"PUBLIC_KEY\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/applications/aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " }\n" + + "}"); + ApplicationDetails response = this.endpoint.parseResponse(stub); + assertEquals("aaaaaaaa-bbbb-cccc-dddd-0123456789ab", response.getId()); + assertEquals("My Application", response.getName()); + + assertNotNull(response.getVoiceApplicationDetails()); + assertNotNull(response.getVoiceApplicationDetails().getWebHooks()); + + WebHook answer = response.getVoiceApplicationDetails().getWebHooks()[0]; + assertEquals("answer_url", answer.getEndpointType()); + assertEquals("https://example.com/answer", answer.getEndpointUrl()); + assertEquals("GET", answer.getHttpMethod()); + + WebHook event = response.getVoiceApplicationDetails().getWebHooks()[1]; + assertEquals("event_url", event.getEndpointType()); + assertEquals("https://example.com/event", event.getEndpointUrl()); + assertEquals("POST", event.getHttpMethod()); + + assertNotNull(response.getKeys()); + ApplicationKeys keys = response.getKeys(); + + assertEquals("PUBLIC_KEY", keys.getPublicKey()); + assertNull(keys.getPrivateKey()); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/BuyNumberEndpointTest.java b/src/test/java/com/nexmo/client/numbers/BuyNumberEndpointTest.java new file mode 100644 index 000000000..86397199e --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/BuyNumberEndpointTest.java @@ -0,0 +1,111 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.TestUtils; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static com.nexmo.client.TestUtils.test429; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; + + +public class BuyNumberEndpointTest { + @Test + public void makeRequest() throws Exception { + BuyNumberEndpoint methodUnderTest = new BuyNumberEndpoint(null); + + RequestBuilder request = methodUnderTest.makeRequest(new BuyNumberRequest("AA", "447700900000")); + + assertEquals("POST", request.getMethod()); + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("AA", params.get("country")); + assertEquals("447700900000", params.get("msisdn")); + } + + @Test + public void parseResponse() throws Exception { + BuyNumberEndpoint methodUnderTest = new BuyNumberEndpoint(null); + + HttpResponse stubResponse = new BasicHttpResponse( + new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), 200, "OK") + ); + + String json = "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}"; + InputStream jsonStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + BasicHttpEntity entity = new BasicHttpEntity(); + entity.setContent(jsonStream); + stubResponse.setEntity(entity); + + BuyNumberResponse response = methodUnderTest.parseResponse(stubResponse); + assertEquals("200", response.getErrorCode()); + assertEquals("success", response.getErrorCodeLabel()); + } + + @Test + public void parseBadRequestResponse() throws Exception { + BuyNumberEndpoint methodUnderTest = new BuyNumberEndpoint(null); + + HttpResponse stubResponse = new BasicHttpResponse( + new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), 400, "OK") + ); + + String json = "{\n" + + " \"error_title\": \"Bad Request\",\n" + + " \"invalid_parameters\": {\n" + + " \"country\": \"Is required.\"\n" + + " },\n" + + " \"type\": \"BAD_REQUEST\"\n" + + "}"; + InputStream jsonStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + BasicHttpEntity entity = new BasicHttpEntity(); + entity.setContent(jsonStream); + stubResponse.setEntity(entity); + + try { + methodUnderTest.parseResponse(stubResponse); + fail("A 400 response should raise a NexmoBadRequestException"); + } catch (NexmoBadRequestException e) { + // This is expected + } + } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new BuyNumberEndpoint(null)); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/BuyNumberRequestAndResponseTest.java b/src/test/java/com/nexmo/client/numbers/BuyNumberRequestAndResponseTest.java new file mode 100644 index 000000000..2b4ae8422 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/BuyNumberRequestAndResponseTest.java @@ -0,0 +1,57 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class BuyNumberRequestAndResponseTest { + @Test + public void testDeserialization() { + BuyNumberResponse response = BuyNumberResponse.fromJson("{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}"); + assertEquals("200", response.getErrorCode()); + assertEquals("success", response.getErrorCodeLabel()); + } + + @Test + public void testBadJson() throws Exception { + try { + BuyNumberResponse.fromJson("this-is-nonsense"); + fail("NexmoUnexpectedException should be raised for bad JSON data."); + } catch (NexmoUnexpectedException nue) { + // Expected + } + } + + @Test + public void testFilterValues() throws Exception { + BuyNumberRequest request = new BuyNumberRequest("YY", "447700900000"); + assertEquals("YY", request.getCountry()); + assertEquals("447700900000", request.getMsisdn()); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/CancelNumberEndpointTest.java b/src/test/java/com/nexmo/client/numbers/CancelNumberEndpointTest.java new file mode 100644 index 000000000..53a3c0593 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/CancelNumberEndpointTest.java @@ -0,0 +1,104 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoBadRequestException; +import com.nexmo.client.NexmoMethodFailedException; +import com.nexmo.client.TestUtils; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Test; + +import java.util.Map; + +import static com.nexmo.client.TestUtils.test429; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; + + +public class CancelNumberEndpointTest { + @Test + public void makeRequest() throws Exception { + CancelNumberEndpoint methodUnderTest = new CancelNumberEndpoint(null); + + RequestBuilder request = methodUnderTest.makeRequest(new CancelNumberRequest("AA", "447700900000")); + + assertEquals("POST", request.getMethod()); + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("AA", params.get("country")); + assertEquals("447700900000", params.get("msisdn")); + } + + @Test + public void parseResponse() throws Exception { + CancelNumberEndpoint methodUnderTest = new CancelNumberEndpoint(null); + String json = "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}"; + + CancelNumberResponse response = methodUnderTest.parseResponse(TestUtils.makeJsonHttpResponse(200, json)); + assertEquals("200", response.getErrorCode()); + assertEquals("success", response.getErrorCodeLabel()); + } + + @Test + public void parseBadRequestResponse() throws Exception { + CancelNumberEndpoint methodUnderTest = new CancelNumberEndpoint(null); + + String json = "{\n" + + " \"error_title\": \"Bad Request\",\n" + + " \"invalid_parameters\": {\n" + + " \"country\": \"Is required.\"\n" + + " },\n" + + " \"type\": \"BAD_REQUEST\"\n" + + "}"; + try { + methodUnderTest.parseResponse(TestUtils.makeJsonHttpResponse(400, json)); + fail("A 400 response should raise a NexmoBadRequestException"); + } catch (NexmoBadRequestException e) { + // This is expected + } + } + + @Test + public void parseMethodFailedResponse() throws Exception { + CancelNumberEndpoint methodUnderTest = new CancelNumberEndpoint(null); + String json = "{\n" + + " \"error_title\": \"Bad Request\",\n" + + " \"invalid_parameters\": {\n" + + " \"country\": \"Is required.\"\n" + + " },\n" + + " \"type\": \"BAD_REQUEST\"\n" + + "}"; + try { + methodUnderTest.parseResponse(TestUtils.makeJsonHttpResponse(500, json)); + fail("A 500 response should raise a NexmoMethodFailedException"); + } catch (NexmoMethodFailedException e) { + // This is expected + } + } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new CancelNumberEndpoint(null)); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/CancelNumberRequestAndResponseTest.java b/src/test/java/com/nexmo/client/numbers/CancelNumberRequestAndResponseTest.java new file mode 100644 index 000000000..81bc94a0d --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/CancelNumberRequestAndResponseTest.java @@ -0,0 +1,56 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class CancelNumberRequestAndResponseTest { + @Test + public void testDeserialization() { + CancelNumberResponse response = CancelNumberResponse.fromJson("{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}"); + assertEquals("200", response.getErrorCode()); + assertEquals("success", response.getErrorCodeLabel()); + } + + @Test + public void testBadJson() throws Exception { + try { + CancelNumberResponse.fromJson("this-is-nonsense"); + fail("NexmoUnexpectedException should be raised for bad JSON data."); + } catch (NexmoUnexpectedException nue) { + // Expected + } + } + + @Test + public void testFilterValues() throws Exception { + CancelNumberRequest request = new CancelNumberRequest("YY", "447700900000"); + assertEquals("YY", request.getCountry()); + assertEquals("447700900000", request.getMsisdn()); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/ListNumbersEndpointTest.java b/src/test/java/com/nexmo/client/numbers/ListNumbersEndpointTest.java new file mode 100644 index 000000000..88bc16308 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/ListNumbersEndpointTest.java @@ -0,0 +1,100 @@ +/* + * 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.numbers; + +import com.nexmo.client.TestUtils; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static com.nexmo.client.TestUtils.test429; +import static org.junit.Assert.assertEquals; + + +public class ListNumbersEndpointTest { + @Test + public void makeRequest() throws Exception { + ListNumbersEndpoint methodUnderTest = new ListNumbersEndpoint(null); + + ListNumbersFilter filter = new ListNumbersFilter(); + filter.setIndex(10); + filter.setSize(20); + filter.setPattern("234"); + filter.setSearchPattern(SearchPattern.STARTS_WITH); + RequestBuilder request = methodUnderTest.makeRequest(filter); + + assertEquals("GET", request.getMethod()); + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("234", params.get("pattern")); + assertEquals("0", params.get("search_pattern")); + assertEquals("10", params.get("index")); + assertEquals("20", params.get("size")); + } + + @Test + public void parseResponse() throws Exception { + ListNumbersEndpoint methodUnderTest = new ListNumbersEndpoint(null); + + HttpResponse stubResponse = new BasicHttpResponse( + new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), 200, "OK") + ); + + String json = "{\n" + + " \"count\": 1,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"moHttpUrl\": \"https://example.com/mo\",\n" + + " \"type\": \"mobile-lvn\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ],\n" + + " \"voiceCallbackType\": \"app\",\n" + + " \"voiceCallbackValue\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " ]\n" + + "}"; + InputStream jsonStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + BasicHttpEntity entity = new BasicHttpEntity(); + entity.setContent(jsonStream); + stubResponse.setEntity(entity); + + ListNumbersResponse response = methodUnderTest.parseResponse(stubResponse); + assertEquals(1, response.getCount()); + } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new ListNumbersEndpoint(null)); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/ListNumbersFilterAndResponseTest.java b/src/test/java/com/nexmo/client/numbers/ListNumbersFilterAndResponseTest.java new file mode 100644 index 000000000..f1a6e950d --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/ListNumbersFilterAndResponseTest.java @@ -0,0 +1,87 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ListNumbersFilterAndResponseTest { + @Test + public void testDeserialization() { + ListNumbersResponse response = ListNumbersResponse.fromJson("{\n" + + " \"count\": 1,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"moHttpUrl\": \"https://example.com/mo\",\n" + + " \"type\": \"mobile-lvn\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ],\n" + + " \"voiceCallbackType\": \"app\",\n" + + " \"voiceCallbackValue\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " ]\n" + + "}"); + assertEquals(1, response.getCount()); + OwnedNumber number = response.getNumbers()[0]; + assertEquals("GB", number.getCountry()); + assertEquals("447700900000", number.getMsisdn()); + assertEquals("https://example.com/mo", number.getMoHttpUrl()); + assertEquals("mobile-lvn", number.getType()); + assertArrayEquals(new String[]{"VOICE", "SMS"}, number.getFeatures()); + assertEquals("app", number.getVoiceCallbackType()); + assertEquals("aaaaaaaa-bbbb-cccc-dddd-0123456789ab", number.getVoiceCallbackValue()); + } + + @Test + public void testBadJson() throws Exception { + try { + ListNumbersResponse.fromJson("this-is-nonsense"); + fail("NexmoUnexpectedException should be raised for bad JSON data."); + } catch (NexmoUnexpectedException nue) { + // Expected + } + } + + @Test + public void testFilterValues() throws Exception { + ListNumbersFilter filter = new ListNumbersFilter(1, 50, "456", SearchPattern.ANYWHERE); + assertEquals(1, (long)filter.getIndex()); + assertEquals(50, (long)filter.getSize()); + assertEquals("456", filter.getPattern()); + assertEquals(1, filter.getSearchPattern().getValue()); + } + + @Test + public void testSearchPatternValues() { + assertEquals(0, SearchPattern.STARTS_WITH.getValue()); + assertEquals(1, SearchPattern.ANYWHERE.getValue()); + assertEquals(2, SearchPattern.ENDS_WITH.getValue()); + + assertEquals(SearchPattern.STARTS_WITH, SearchPattern.valueOf("STARTS_WITH")); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/NumbersClientTest.java b/src/test/java/com/nexmo/client/numbers/NumbersClientTest.java new file mode 100644 index 000000000..5ad8b3caf --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/NumbersClientTest.java @@ -0,0 +1,194 @@ +/* + * 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.numbers; + +import com.nexmo.client.HttpWrapper; +import com.nexmo.client.TestUtils; +import com.nexmo.client.auth.AuthCollection; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; +import org.junit.Test; + +import java.io.ByteArrayInputStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class NumbersClientTest { + private TestUtils testUtils = new TestUtils(); + + private HttpWrapper stubHttpWrapper(int statusCode, String content) throws Exception { + HttpClient client = mock(HttpClient.class); + + HttpResponse response = mock(HttpResponse.class); + StatusLine sl = mock(StatusLine.class); + HttpEntity entity = mock(HttpEntity.class); + + when(client.execute(any(HttpUriRequest.class))).thenReturn(response); + when(entity.getContent()).thenReturn(new ByteArrayInputStream(content.getBytes("UTF-8"))); + when(sl.getStatusCode()).thenReturn(statusCode); + when(response.getStatusLine()).thenReturn(sl); + when(response.getEntity()).thenReturn(entity); + + byte[] keyBytes = testUtils.loadKey("test/keys/application_key"); + AuthCollection authCollection = new AuthCollection(); + authCollection.add(new TokenAuthMethod( + "dummyKey", + "dummySecret" + )); + + HttpWrapper wrapper = new HttpWrapper(authCollection); + wrapper.setHttpClient(client); + + return wrapper; + } + + @Test + public void testListNumbers() throws Exception { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"count\": 1,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"moHttpUrl\": \"https://example.com/mo\",\n" + + " \"type\": \"mobile-lvn\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ],\n" + + " \"voiceCallbackType\": \"app\",\n" + + " \"voiceCallbackValue\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " ]\n" + + "}")); + ListNumbersResponse response = client.listNumbers(); + assertEquals(1, response.getCount()); + } + + @Test + public void testListNumberWithParams() throws Exception { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"count\": 1,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"moHttpUrl\": \"https://example.com/mo\",\n" + + " \"type\": \"mobile-lvn\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ],\n" + + " \"voiceCallbackType\": \"app\",\n" + + " \"voiceCallbackValue\": \"aaaaaaaa-bbbb-cccc-dddd-0123456789ab\"\n" + + " }\n" + + " ]\n" + + "}")); + + ListNumbersFilter filter = new ListNumbersFilter(); + filter.setIndex(10); + filter.setSize(20); + filter.setPattern("234"); + filter.setSearchPattern(SearchPattern.ENDS_WITH); + ListNumbersResponse response = client.listNumbers(filter); + assertEquals(1, response.getCount()); + } + + @Test + public void testSearchNumbers() throws Exception { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"count\": 4,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"cost\": \"0.50\",\n" + + " \"type\": \"mobile\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + SearchNumbersResponse response = client.searchNumbers("YY"); + assertEquals(4, response.getCount()); + + } + + @Test + public void testCancelNumber() throws Exception { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}")); + + client.cancelNumber("AA", "447700900000"); + } + + @Test + public void testBuyNumber() throws Exception { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}")); + + client.buyNumber("AA", "447700900000"); + } + + @Test + public void testUpdateNumber() throws Exception { + try { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}")); + client.updateNumber(new UpdateNumberRequest( + "447700900328", "UK" + )); + } catch (Exception e) { + fail("Parsing a valid response should not raise an exception"); + } + } + + @Test + public void testLinkNumber() throws Exception { + try { + NumbersClient client = new NumbersClient(stubHttpWrapper(200, "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}")); + client.linkNumber("447700900328", "UK", "my-app-id"); + } catch (Exception e) { + fail("Parsing a valid response should not raise an exception"); + } + + } +} diff --git a/src/test/java/com/nexmo/client/numbers/SearchNumbersEndpointTest.java b/src/test/java/com/nexmo/client/numbers/SearchNumbersEndpointTest.java new file mode 100644 index 000000000..bdd7dcc41 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/SearchNumbersEndpointTest.java @@ -0,0 +1,127 @@ +/* + * 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.numbers; + +import com.nexmo.client.TestUtils; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static com.nexmo.client.TestUtils.test429; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + + +public class SearchNumbersEndpointTest { + @Test + public void makeRequest() throws Exception { + SearchNumbersEndpoint methodUnderTest = new SearchNumbersEndpoint(null); + + SearchNumbersFilter filter = new SearchNumbersFilter("BB"); + filter.setIndex(10); + filter.setSize(20); + filter.setPattern("234"); + filter.setFeatures(new String[]{"SMS", "VOICE"}); + filter.setSearchPattern(SearchPattern.STARTS_WITH); + RequestBuilder request = methodUnderTest.makeRequest(filter); + + assertEquals("GET", request.getMethod()); + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("BB", params.get("country")); + assertEquals("SMS,VOICE", params.get("features")); + assertEquals("234", params.get("pattern")); + assertEquals("0", params.get("search_pattern")); + assertEquals("10", params.get("index")); + assertEquals("20", params.get("size")); + } + + @Test + public void testNullFeatureParam() throws Exception { + SearchNumbersEndpoint methodUnderTest = new SearchNumbersEndpoint(null); + + SearchNumbersFilter filter = new SearchNumbersFilter("BB"); + RequestBuilder request = methodUnderTest.makeRequest(filter); + + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("BB", params.get("country")); + assertNull(params.get("features")); + } + + @Test + public void testEmptyFeature() throws Exception { + SearchNumbersEndpoint methodUnderTest = new SearchNumbersEndpoint(null); + + SearchNumbersFilter filter = new SearchNumbersFilter("BB"); + filter.setFeatures(new String[]{}); + RequestBuilder request = methodUnderTest.makeRequest(filter); + + Map params = TestUtils.makeParameterMap(request.getParameters()); + assertEquals("BB", params.get("country")); + assertNull(params.get("features")); + } + + @Test + public void testParseResponse() throws Exception { + SearchNumbersEndpoint methodUnderTest = new SearchNumbersEndpoint(null); + + HttpResponse stubResponse = new BasicHttpResponse( + new BasicStatusLine(new ProtocolVersion("1.1", 1, 1), 200, "OK") + ); + + String json = "{\n" + + " \"count\": 4,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"cost\": \"0.50\",\n" + + " \"type\": \"mobile\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + InputStream jsonStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + BasicHttpEntity entity = new BasicHttpEntity(); + entity.setContent(jsonStream); + stubResponse.setEntity(entity); + + SearchNumbersResponse response = methodUnderTest.parseResponse(stubResponse); + assertEquals(4, response.getCount()); + } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new SearchNumbersEndpoint(null)); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/SearchNumbersFilterAndResponseTest.java b/src/test/java/com/nexmo/client/numbers/SearchNumbersFilterAndResponseTest.java new file mode 100644 index 000000000..bb0ce16c8 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/SearchNumbersFilterAndResponseTest.java @@ -0,0 +1,91 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class SearchNumbersFilterAndResponseTest { + @Test + public void testDeserialization() { + SearchNumbersResponse response = SearchNumbersResponse.fromJson("{\n" + + " \"count\": 4,\n" + + " \"numbers\": [\n" + + " {\n" + + " \"country\": \"GB\",\n" + + " \"msisdn\": \"447700900000\",\n" + + " \"cost\": \"0.50\",\n" + + " \"type\": \"mobile\",\n" + + " \"features\": [\n" + + " \"VOICE\",\n" + + " \"SMS\"\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"); + assertEquals(4, response.getCount()); + AvailableNumber number = response.getNumbers()[0]; + assertEquals("GB", number.getCountry()); + assertEquals("447700900000", number.getMsisdn()); + assertEquals("0.50", number.getCost()); + assertEquals("mobile", number.getType()); + assertArrayEquals(new String[]{"VOICE", "SMS"}, number.getFeatures()); + } + + @Test + public void testBadJson() throws Exception { + try { + SearchNumbersResponse.fromJson("this-is-nonsense"); + fail("NexmoUnexpectedException should be raised for bad JSON data."); + } catch (NexmoUnexpectedException nue) { + // Expected + } + } + + @Test + public void testFilterValues() throws Exception { + SearchNumbersFilter filter = new SearchNumbersFilter("GG"); + filter.setIndex(1); + filter.setSize(50); + filter.setPattern("456"); + filter.setSearchPattern(SearchPattern.STARTS_WITH); + filter.setFeatures(new String[] {"SMS"}); + + assertEquals("GG", filter.getCountry()); + assertEquals(1, (long)filter.getIndex()); + assertEquals(50, (long)filter.getSize()); + assertEquals("456", filter.getPattern()); + assertEquals(0, filter.getSearchPattern().getValue()); + assertArrayEquals(new String[] {"SMS"}, filter.getFeatures()); + } + + @Test + public void testSearchPatternValues() { + assertEquals(0, SearchPattern.STARTS_WITH.getValue()); + assertEquals(1, SearchPattern.ANYWHERE.getValue()); + assertEquals(2, SearchPattern.ENDS_WITH.getValue()); + + assertEquals(SearchPattern.STARTS_WITH, SearchPattern.valueOf("STARTS_WITH")); + } +} diff --git a/src/test/java/com/nexmo/client/numbers/UpdateNumberEndpointTest.java b/src/test/java/com/nexmo/client/numbers/UpdateNumberEndpointTest.java new file mode 100644 index 000000000..0643aae11 --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/UpdateNumberEndpointTest.java @@ -0,0 +1,119 @@ +/* + * 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.numbers; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class UpdateNumberEndpointTest { + private UpdateNumberEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new UpdateNumberEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new UpdateNumberRequest( + "447700900013", "UK" + )); + assertEquals("POST", builder.getMethod()); + assertEquals("https://rest.nexmo.com/number/update", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(2, params.size()); + assertEquals("447700900013", params.get("msisdn")); + assertEquals("UK", params.get("country")); + } + + @Test + public void testMakeRequestWithOptionalParams() throws Exception { + UpdateNumberRequest request = new UpdateNumberRequest( + "447700900013", "UK" + ); + request.setMoHttpUrl("https://api.example.com/mo"); + request.setMoSmppSysType("inbound"); + request.setVoiceCallbackValue("1234-5678-9123-4567"); + request.setVoiceCallbackType(UpdateNumberRequest.CallbackType.APP); + request.setVoiceStatusCallback("https://api.example.com/callback"); + + RequestBuilder builder = this.endpoint.makeRequest(request); + + assertEquals("POST", builder.getMethod()); + assertEquals("https://rest.nexmo.com/number/update", builder.build().getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(7, params.size()); + assertEquals("447700900013", params.get("msisdn")); + assertEquals("UK", params.get("country")); + assertEquals("https://api.example.com/mo", params.get("moHttpUrl")); + assertEquals("inbound", params.get("moSmppSysType")); + assertEquals("1234-5678-9123-4567", params.get("voiceCallbackValue")); + assertEquals("app", params.get("voiceCallbackType")); + assertEquals("https://api.example.com/callback", params.get("voiceStatusCallback")); + } + + @Test + public void testParseResponse() throws Exception { + try { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"error-code\":\"200\",\n" + + " \"error-code-label\":\"success\"\n" + + "}"); + this.endpoint.parseResponse(stub); + } catch (Exception e) { + fail("Parsing a 200 response should not raise an error."); + } + } + + @Test + public void testParseErrorResponse() throws Exception { + try { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"error-code\":\"500\",\n" + + " \"error-code-label\":\"There was an error\"\n" + + "}"); + this.endpoint.parseResponse(stub); + fail("An exception should have been thrown here."); + } catch (Exception e) { + assertEquals("There was an error", e.getMessage()); + // This is expected. + } + } +} diff --git a/src/test/java/com/nexmo/client/numbers/UpdateNumberResponseTest.java b/src/test/java/com/nexmo/client/numbers/UpdateNumberResponseTest.java new file mode 100644 index 000000000..4211b7c8b --- /dev/null +++ b/src/test/java/com/nexmo/client/numbers/UpdateNumberResponseTest.java @@ -0,0 +1,39 @@ +/* + * 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.numbers; + +import com.nexmo.client.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class UpdateNumberResponseTest { + @Test + public void testJsonError() throws Exception { + try { + UpdateNumberResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} \ No newline at end of file diff --git a/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesEndpointTest.java b/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesEndpointTest.java new file mode 100644 index 000000000..f4a409ea9 --- /dev/null +++ b/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesEndpointTest.java @@ -0,0 +1,97 @@ +/* + * 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.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Map; + +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.*; + +public class SearchRejectedMessagesEndpointTest { + private SearchRejectedMessagesEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new SearchRejectedMessagesEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new SearchRejectedMessagesRequest( + new GregorianCalendar(2017, Calendar.OCTOBER, 22).getTime(), + "447700900737" + )); + // TODO: Check method and URL are correct: + assertEquals("GET", builder.getMethod()); + assertThat(builder.build().getURI().toString(), startsWith("https://rest.nexmo.com/search/rejections?")); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals(2, params.size()); + assertEquals("2017-10-22", params.get("date")); + assertEquals("447700900737", params.get("to")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"count\": 1,\n" + + " \"items\": [\n" + + " {\n" + + " \"account-id\": \"key\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456890\",\n" + + " \"date-received\": \"2012-05-02 16:03:00\",\n" + + " \"error-code\": 9,\n" + + " \"error-code-label\": \"partner quota exceeded -- Your pre-pay account does not have sufficient credit to process this message\"\n" + + " }\n" + + " ]\n" + + "}\n"); + SearchRejectedMessagesResponse response = this.endpoint.parseResponse(stub); + assertEquals(1, response.getCount()); + assertNotNull(response.getItems()); + assertEquals(1, response.getItems().length); + RejectedMessage m = response.getItems()[0]; + assertEquals("key", m.getAccountId()); + assertEquals("MyApp", m.getFrom()); + assertEquals("123456890", m.getTo()); + assertEquals( + new GregorianCalendar(2012, Calendar.MAY, 2, 16, 3, 0).getTime(), + m.getDateReceived()); + assertEquals(9, m.getErrorCode().longValue()); + assertEquals("partner quota exceeded -- Your pre-pay account does not have sufficient credit to process this message", m.getErrorCodeLabel()); + } +} diff --git a/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesResponseTest.java b/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesResponseTest.java new file mode 100644 index 000000000..371532420 --- /dev/null +++ b/src/test/java/com/nexmo/client/sms/SearchRejectedMessagesResponseTest.java @@ -0,0 +1,39 @@ +/* + * 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.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class SearchRejectedMessagesResponseTest { + @Test + public void testJsonError() throws Exception { + try { + SearchRejectedMessagesResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} \ No newline at end of file diff --git a/src/test/java/com/nexmo/client/sms/SearchSmsEndpointTest.java b/src/test/java/com/nexmo/client/sms/SearchSmsEndpointTest.java new file mode 100644 index 000000000..5f7e1de26 --- /dev/null +++ b/src/test/java/com/nexmo/client/sms/SearchSmsEndpointTest.java @@ -0,0 +1,160 @@ +/* + * 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.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.*; + +public class SearchSmsEndpointTest { + private SmsSearchEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new SmsSearchEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeSingleIdRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new SmsIdSearchRequest("one-id")); + assertEquals("GET", builder.getMethod()); + assertThat(builder.build().getURI().toString(), startsWith("https://rest.nexmo.com/search/messages?")); + + Map> params = TestUtils.makeFullParameterMap(builder.getParameters()); + assertThat(params.size(), equalTo(1)); + List ids = params.get("ids"); + assertNotNull(ids); + assertEquals(1, ids.size()); + assertEquals("one-id", ids.get(0)); + } + + @Test + public void testMakeMultipleIdRequest() throws Exception { + SmsIdSearchRequest request = new SmsIdSearchRequest("one-id"); + request.addId("two-id"); + RequestBuilder builder = this.endpoint.makeRequest(request); + assertEquals("GET", builder.getMethod()); + assertThat(builder.build().getURI().toString(), startsWith("https://rest.nexmo.com/search/messages?")); + + Map> params = TestUtils.makeFullParameterMap(builder.getParameters()); + assertThat(params.size(), equalTo(1)); + List ids = params.get("ids"); + assertNotNull(ids); + assertEquals(2, ids.size()); + assertEquals("one-id", ids.get(0)); + assertEquals("two-id", ids.get(1)); + } + + @Test + public void testMakeDateRequest() throws Exception { + SmsDateSearchRequest request = new SmsDateSearchRequest( + new GregorianCalendar(2017, GregorianCalendar.SEPTEMBER, 22).getTime(), + "447700900510" + ); + RequestBuilder builder = this.endpoint.makeRequest(request); + assertEquals("GET", builder.getMethod()); + assertThat(builder.build().getURI().toString(), startsWith("https://rest.nexmo.com/search/messages?")); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertThat(params.size(), equalTo(2)); + assertThat(params.get("date"), equalTo("2017-09-22")); + assertThat(params.get("to"), equalTo("447700900510")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"count\": 2,\n" + + " \"items\": [\n" + + " {\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" + + " },\n" + + " {\n" + + " \"message-id\": \"00A0B0C1\",\n" + + " \"account-id\": \"key\",\n" + + " \"network\": \"20810\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456891\",\n" + + " \"body\": \"foo bar\",\n" + + " \"price\": \"0.04500000\",\n" + + " \"date-received\": \"2011-11-25 17:03:00\",\n" + + " \"final-status\": \"DELIVRD\",\n" + + " \"date-closed\": \"2011-11-25 18:03:00\",\n" + + " \"latency\": 14151,\n" + + " \"type\": \"MT\"\n" + + " }\n" + + " ]\n" + + "}\n"); + SearchSmsResponse response = this.endpoint.parseResponse(stub); + + assertThat(response.getCount(), equalTo(2)); + + SmsDetails details = response.getItems()[0]; + assertEquals("00A0B0C0", details.getMessageId()); + assertEquals("key", details.getAccountId()); + assertEquals("20810", details.getNetwork()); + assertEquals("MyApp", details.getFrom()); + assertEquals("123456890", details.getTo()); + assertEquals("hello world", details.getBody()); + assertEquals("0.04500000", details.getPrice()); + assertEquals( + new GregorianCalendar(2011, Calendar.NOVEMBER, 25, 16, 03, 00).getTime(), + details.getDateReceived()); + assertEquals("DELIVRD", details.getFinalStatus()); + assertEquals( + new GregorianCalendar(2011, Calendar.NOVEMBER, 25, 16, 03, 00).getTime(), + details.getDateClosed()); + assertEquals(11151, details.getLatency().longValue()); + assertEquals("MT", details.getType()); + + + } +} diff --git a/src/test/java/com/nexmo/client/sms/SearchSmsResponseTest.java b/src/test/java/com/nexmo/client/sms/SearchSmsResponseTest.java new file mode 100644 index 000000000..cf8e4aba3 --- /dev/null +++ b/src/test/java/com/nexmo/client/sms/SearchSmsResponseTest.java @@ -0,0 +1,39 @@ +/* + * 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.NexmoUnexpectedException; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class SearchSmsResponseTest { + @Test + public void testJsonError() throws Exception { + try { + SearchSmsResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} \ No newline at end of file diff --git a/src/test/java/com/nexmo/client/sms/SendMessageEndpointTest.java b/src/test/java/com/nexmo/client/sms/SendMessageEndpointTest.java index de234fa59..cad6881bd 100644 --- a/src/test/java/com/nexmo/client/sms/SendMessageEndpointTest.java +++ b/src/test/java/com/nexmo/client/sms/SendMessageEndpointTest.java @@ -69,6 +69,19 @@ public void testConstructParamsText() throws Exception { assertContainsParam(params, "text", "Test"); } + @Test + public void testStatusReportRequiredSetter() throws Exception { + Message message = new TextMessage("TestSender", "not-a-number", "Test"); + message.setStatusReportRequired(true); + List params = endpoint.makeRequest(message).getParameters(); + + assertContainsParam(params, "from", "TestSender"); + assertContainsParam(params, "to", "not-a-number"); + assertContainsParam(params, "type", "text"); + assertContainsParam(params, "status-report-req", "1"); + assertContainsParam(params, "text", "Test"); + } + @Test public void testConstructParamsUnicode() throws Exception { Message message = new TextMessage("TestSender", "not-a-number", "Test", true); diff --git a/src/test/java/com/nexmo/client/sms/SmsClientTest.java b/src/test/java/com/nexmo/client/sms/SmsClientTest.java index fc5f154f8..d7f790309 100644 --- a/src/test/java/com/nexmo/client/sms/SmsClientTest.java +++ b/src/test/java/com/nexmo/client/sms/SmsClientTest.java @@ -31,14 +31,18 @@ import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpUriRequest; +import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Test; import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; +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.mockito.Matchers.any; import static org.mockito.Mockito.mock; @@ -115,5 +119,109 @@ public void testSubmitMessageHttpError() throws Exception { } } + @Test + public void testSearchMessagesId() throws Exception { + this.wrapper.setHttpClient(this.stubHttpClient(200, "{\n" + + " \"count\": 2,\n" + + " \"items\": [\n" + + " {\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" + + " },\n" + + " {\n" + + " \"message-id\": \"00A0B0C1\",\n" + + " \"account-id\": \"key\",\n" + + " \"network\": \"20810\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456891\",\n" + + " \"body\": \"foo bar\",\n" + + " \"price\": \"0.04500000\",\n" + + " \"date-received\": \"2011-11-25 17:03:00\",\n" + + " \"final-status\": \"DELIVRD\",\n" + + " \"date-closed\": \"2011-11-25 18:03:00\",\n" + + " \"latency\": 14151,\n" + + " \"type\": \"MT\"\n" + + " }\n" + + " ]\n" + + "}\n")); + + SearchSmsResponse response = client.searchMessages("an-id"); + assertThat(response.getCount(), CoreMatchers.equalTo(2)); + } + @Test + public void testSearchMessagesDate() throws Exception { + this.wrapper.setHttpClient(this.stubHttpClient(200, "{\n" + + " \"count\": 2,\n" + + " \"items\": [\n" + + " {\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" + + " },\n" + + " {\n" + + " \"message-id\": \"00A0B0C1\",\n" + + " \"account-id\": \"key\",\n" + + " \"network\": \"20810\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456891\",\n" + + " \"body\": \"foo bar\",\n" + + " \"price\": \"0.04500000\",\n" + + " \"date-received\": \"2011-11-25 17:03:00\",\n" + + " \"final-status\": \"DELIVRD\",\n" + + " \"date-closed\": \"2011-11-25 18:03:00\",\n" + + " \"latency\": 14151,\n" + + " \"type\": \"MT\"\n" + + " }\n" + + " ]\n" + + "}\n")); + + SearchSmsResponse response = client.searchMessages( + new GregorianCalendar(2017, Calendar.OCTOBER, 22).getTime(), + "447700900983" + ); + assertThat(response.getCount(), CoreMatchers.equalTo(2)); + } + + @Test + public void testSearchRejected() throws Exception { + this.wrapper.setHttpClient(this.stubHttpClient(200, "{\n" + + " \"count\": 1,\n" + + " \"items\": [\n" + + " {\n" + + " \"account-id\": \"key\",\n" + + " \"from\": \"MyApp\",\n" + + " \"to\": \"123456890\",\n" + + " \"date-received\": \"2012-05-02 16:03:00\",\n" + + " \"error-code\": 9,\n" + + " \"error-code-label\": \"partner quota exceeded -- Your pre-pay account does not have sufficient credit to process this message\"\n" + + " }\n" + + " ]\n" + + "}\n")); + + SearchRejectedMessagesResponse response = client.searchRejectedMessages( + new GregorianCalendar(2017, Calendar.OCTOBER, 22).getTime(), + "447700900983" + ); + assertThat(response.getCount(), CoreMatchers.equalTo(1)); + } } diff --git a/src/test/java/com/nexmo/client/verify/VerifyClientTest.java b/src/test/java/com/nexmo/client/verify/VerifyClientTest.java index e5b09f470..682e2ef6e 100644 --- a/src/test/java/com/nexmo/client/verify/VerifyClientTest.java +++ b/src/test/java/com/nexmo/client/verify/VerifyClientTest.java @@ -154,7 +154,7 @@ public void testCheckError() throws Exception { @Test public void testCheckInvalidResponse() throws Exception { wrapper.setHttpClient(this.stubHttpClient( - 500, + 200, "\n" + "")); @@ -390,7 +390,7 @@ public void testSearchDodgyDates() throws Exception { @Test public void testSearchHttpError() throws Exception { - wrapper.setHttpClient(this.stubHttpClient(500, "\n" + + wrapper.setHttpClient(this.stubHttpClient(200, "\n" + "")); try { client.search("a-random-request-id"); diff --git a/src/test/java/com/nexmo/client/verify/endpoints/ControlEndpointTest.java b/src/test/java/com/nexmo/client/verify/endpoints/ControlEndpointTest.java new file mode 100644 index 000000000..3e77e53c7 --- /dev/null +++ b/src/test/java/com/nexmo/client/verify/endpoints/ControlEndpointTest.java @@ -0,0 +1,95 @@ +/* + * 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.verify.endpoints; + +import com.nexmo.client.TestUtils; +import com.nexmo.client.auth.TokenAuthMethod; +import com.nexmo.client.verify.ControlRequest; +import com.nexmo.client.verify.ControlResponse; +import com.nexmo.client.verify.VerifyControlCommand; +import com.nexmo.client.verify.VerifyException; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.RequestBuilder; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class ControlEndpointTest { + private ControlEndpoint endpoint; + + @Before + public void setUp() throws Exception { + this.endpoint = new ControlEndpoint(null); + } + + @Test + public void testGetAcceptableAuthMethods() throws Exception { + Class[] auths = this.endpoint.getAcceptableAuthMethods(); + assertArrayEquals(new Class[]{TokenAuthMethod.class}, auths); + } + + @Test + public void testMakeRequest() throws Exception { + RequestBuilder builder = this.endpoint.makeRequest(new ControlRequest( + "request-id", VerifyControlCommand.CANCEL + )); + assertEquals("POST", builder.getMethod()); + assertEquals("https://api.nexmo.com/verify/control/json", builder.build() + .getURI().toString()); + + Map params = TestUtils.makeParameterMap(builder.getParameters()); + assertEquals("request-id", params.get("request_id")); + assertEquals("cancel", params.get("cmd")); + } + + @Test + public void testParseResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"status\":\"0\",\n" + + " \"command\":\"cancel\"\n" + + "}"); + ControlResponse response = this.endpoint.parseResponse(stub); + assertEquals("0", response.getStatus()); + assertEquals(VerifyControlCommand.CANCEL, response.getCommand()); + } + + @Test + public void testParseErrorResponse() throws Exception { + HttpResponse stub = TestUtils.makeJsonHttpResponse(200, "{\n" + + " \"error_text\": \"Missing username\",\n" + + " \"status\": \"2\"\n" + + "}"); + try { + ControlResponse response = this.endpoint.parseResponse(stub); + fail("Parsing an error response should throw an exception."); + } catch(VerifyException exc){ + assertEquals("2", exc.getStatus()); + assertEquals("Missing username", exc.getErrorText()); + } + + } + } diff --git a/src/test/java/com/nexmo/client/verify/endpoints/ControlResponseTest.java b/src/test/java/com/nexmo/client/verify/endpoints/ControlResponseTest.java new file mode 100644 index 000000000..0e557a2eb --- /dev/null +++ b/src/test/java/com/nexmo/client/verify/endpoints/ControlResponseTest.java @@ -0,0 +1,52 @@ +/* + * 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.verify.endpoints; + +import com.nexmo.client.NexmoUnexpectedException; +import com.nexmo.client.verify.ControlResponse; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class ControlResponseTest { + + @Test + public void testParseError() throws Exception { + ControlResponse response = ControlResponse.fromJson("{\n" + + " \"error_text\": \"Missing username\",\n" + + " \"status\": \"2\"\n" + + "}"); + assertEquals("2", response.getStatus()); + assertEquals("Missing username", response.getErrorText()); + } + + @Test + public void testBadJson() throws Exception { + try { + ControlResponse.fromJson("blarg"); + fail("Deserializing nonsense JSON should result in a NexmoUnexpectedException"); + } catch (NexmoUnexpectedException nue) { + // This is expected + } + } +} diff --git a/src/test/java/com/nexmo/client/verify/endpoints/SearchEndpointTest.java b/src/test/java/com/nexmo/client/verify/endpoints/SearchEndpointTest.java index 5094018d1..d03e7c667 100644 --- a/src/test/java/com/nexmo/client/verify/endpoints/SearchEndpointTest.java +++ b/src/test/java/com/nexmo/client/verify/endpoints/SearchEndpointTest.java @@ -30,7 +30,10 @@ import javax.xml.parsers.ParserConfigurationException; import java.util.GregorianCalendar; -import static org.junit.Assert.*; +import static com.nexmo.client.TestUtils.test429; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class SearchEndpointTest { @@ -156,7 +159,7 @@ public void testCheckInvalidStatus() throws Exception { " EUR\n" + " FAILED\n" + ""); - fail("Invalid status value should throw NexmoResponseParseException"); + fail("Invalid status value should throw NexmoResponseParseException"); } catch (NexmoResponseParseException e) { // this is expected @@ -167,27 +170,27 @@ public void testCheckInvalidStatus() throws Exception { public void testBadDateInCheck() throws Exception { SearchResult[] rs = client.parseSearchResponse( "\n" + - "\n" + - " a-random-request-id\n" + - " account-id\n" + - " not-a-number\n" + - " verify\n" + - " 2016-10-19 11:18:56\n" + - " 2016-10-19 11:20:00\n" + - " \n" + - " \n" + - " THIS IS NOT A DATE\n" + - " 1234\n" + - " INVALID\n" + - " \n" + - " \n" + - " \n" + - " 2016-10-19 11:18:56\n" + - " 2016-10-19 11:18:56\n" + - " 0\n" + - " EUR\n" + - " FAILED\n" + - ""); + "\n" + + " a-random-request-id\n" + + " account-id\n" + + " not-a-number\n" + + " verify\n" + + " 2016-10-19 11:18:56\n" + + " 2016-10-19 11:20:00\n" + + " \n" + + " \n" + + " THIS IS NOT A DATE\n" + + " 1234\n" + + " INVALID\n" + + " \n" + + " \n" + + " \n" + + " 2016-10-19 11:18:56\n" + + " 2016-10-19 11:18:56\n" + + " 0\n" + + " EUR\n" + + " FAILED\n" + + ""); assertNull(rs[0].getChecks().get(0).getDate()); } @@ -279,4 +282,9 @@ public void testParseCheckXmlNodeUnrecognizedElement() throws Exception { ""); assertEquals(new GregorianCalendar(2016, 9, 19, 11, 20, 0).getTime(), rs[0].getChecks().get(0).getDate()); } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new SearchEndpoint(null)); + } } diff --git a/src/test/java/com/nexmo/client/voice/CallModifierTest.java b/src/test/java/com/nexmo/client/voice/CallModifierTest.java index 5b8eef2f8..d82c392cc 100644 --- a/src/test/java/com/nexmo/client/voice/CallModifierTest.java +++ b/src/test/java/com/nexmo/client/voice/CallModifierTest.java @@ -27,13 +27,12 @@ import static org.junit.Assert.*; - public class CallModifierTest { private CallModifier callModifier; @Before public void setUp() throws Exception { - callModifier = new CallModifier("abc-123", "hangup"); + callModifier = new CallModifier("abc-123", ModifyCallAction.HANGUP); } @Test @@ -43,14 +42,7 @@ public void getUuid() throws Exception { @Test public void getAction() throws Exception { - assertEquals("hangup", callModifier.getAction()); - } - - @Test - public void setAction() throws Exception { - //this is not a real action - callModifier.setAction("pause"); - assertEquals("pause", callModifier.getAction()); + assertEquals(ModifyCallAction.HANGUP, callModifier.getAction()); } @Test @@ -58,5 +50,4 @@ public void toJson() throws Exception { String jsonString = "{\"action\":\"hangup\"}"; assertEquals(jsonString, callModifier.toJson()); } - -} \ No newline at end of file +} diff --git a/src/test/java/com/nexmo/client/voice/SendDtmfMethodTest.java b/src/test/java/com/nexmo/client/voice/SendDtmfMethodTest.java index 46ce6dd44..1ec07f0d1 100644 --- a/src/test/java/com/nexmo/client/voice/SendDtmfMethodTest.java +++ b/src/test/java/com/nexmo/client/voice/SendDtmfMethodTest.java @@ -39,6 +39,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; +import static com.nexmo.client.TestUtils.test429; import static org.junit.Assert.assertEquals; @@ -81,4 +82,8 @@ public void parseResponse() throws Exception { assertEquals("ssf61863-4a51-ef6b-11e1-w6edebcf93bb", response.getUuid()); } + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new SendDtmfMethod(null)); + } } diff --git a/src/test/java/com/nexmo/client/voice/TransferCallPayloadTest.java b/src/test/java/com/nexmo/client/voice/TransferCallPayloadTest.java new file mode 100644 index 000000000..bf43c18d8 --- /dev/null +++ b/src/test/java/com/nexmo/client/voice/TransferCallPayloadTest.java @@ -0,0 +1,41 @@ +package com.nexmo.client.voice;/* + * 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. + */ + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class TransferCallPayloadTest { + @Test + public void transferJson() throws Exception { + String expected = "{\"action\":\"transfer\",\"destination\":{\"type\":\"ncco\",\"url\":[\"https://example" + + ".com/ncco\"]}}"; + String actual = CallModifier.transferCall("not-a-uuid", "https://example.com/ncco").toJson(); + System.out.println(actual); + assertEquals(expected, actual); + } + + @Test + public void testTypeValueOf() throws Exception { + assertEquals(TransferDestination.Type.NCCO, TransferDestination.Type.valueOf("NCCO")); + } +} diff --git a/src/test/java/com/nexmo/client/voice/VoiceClientTest.java b/src/test/java/com/nexmo/client/voice/VoiceClientTest.java index 25747782c..6333a6149 100644 --- a/src/test/java/com/nexmo/client/voice/VoiceClientTest.java +++ b/src/test/java/com/nexmo/client/voice/VoiceClientTest.java @@ -177,7 +177,23 @@ public void testSendDtmf() throws Exception { @Test public void testModifyCall() throws Exception { VoiceClient client = new VoiceClient(stubHttpWrapper(200, "{\"message\":\"Received\"}")); - ModifyCallResponse call = client.modifyCall("93137ee3-580e-45f7-a61a-e0b5716000ef", "hangup"); + ModifyCallResponse call = client.modifyCall("93137ee3-580e-45f7-a61a-e0b5716000ef", ModifyCallAction.HANGUP); + assertEquals("Received", call.getMessage()); + } + + @Test + public void testModifyCall2() throws Exception { + VoiceClient client = new VoiceClient(stubHttpWrapper(200, "{\"message\":\"Received\"}")); + ModifyCallResponse call = client.modifyCall( + new CallModifier("93137ee3-580e-45f7-a61a-e0b5716000ef", ModifyCallAction.MUTE)); + assertEquals("Received", call.getMessage()); + } + + @Test + public void testTransferCall() throws Exception { + VoiceClient client = new VoiceClient(stubHttpWrapper(200, "{\"message\":\"Received\"}")); + ModifyCallResponse call = client.transferCall( + "93137ee3-580e-45f7-a61a-e0b5716000ef", "https://example.com/ncco2"); assertEquals("Received", call.getMessage()); } diff --git a/src/test/java/com/nexmo/client/voice/endpoints/CallInfoTest.java b/src/test/java/com/nexmo/client/voice/endpoints/CallInfoTest.java index 3864d0d5f..bf3c21617 100644 --- a/src/test/java/com/nexmo/client/voice/endpoints/CallInfoTest.java +++ b/src/test/java/com/nexmo/client/voice/endpoints/CallInfoTest.java @@ -35,6 +35,32 @@ import static org.junit.Assert.assertEquals; public class CallInfoTest { + String jsonWithPlaceholder = "{\n" + + " \"uuid\": \"93137ee3-580e-45f7-a61a-e0b5716000ef\",\n" + + " \"status\": \"PLACEHOLDER\",\n" + + " \"direction\": \"outbound\",\n" + + " \"rate\": \"0.02400000\",\n" + + " \"price\": \"0.00280000\",\n" + + " \"duration\": \"7\",\n" + + " \"network\": \"23410\",\n" + + " \"conversation_uuid\": \"aa17bd11-c895-4225-840d-30dc38c31e50\",\n" + + " \"start_time\": \"2017-01-13T13:55:02.000Z\",\n" + + " \"end_time\": \"2017-01-13T13:55:09.000Z\",\n" + + " \"to\": {\n" + + " \"type\": \"phone\",\n" + + " \"number\": \"447700900104\"\n" + + " },\n" + + " \"from\": {\n" + + " \"type\": \"phone\",\n" + + " \"number\": \"447700900105\"\n" + + " },\n" + + " \"_links\": {\n" + + " \"self\": {\n" + + " \"href\": \"/v1/calls/93137ee3-580e-45f7-a61a-e0b5716000ef\"\n" + + " }\n" + + " }\n" + + "}\n"; + @Test public void testJson() throws Exception { String json = "{\n" + @@ -87,8 +113,63 @@ public void testJson() throws Exception { record.getEndTime()); assertEquals(new PhoneEndpoint("447700900104"), record.getTo()); assertEquals(new PhoneEndpoint("447700900105"), record.getFrom()); + } + + + @Test + public void testStatusStarted() throws Exception { + testStatus("started", CallStatus.STARTED); + } + + @Test + public void testStatusRinging() throws Exception { + testStatus("ringing", CallStatus.RINGING); + } + + @Test + public void testStatusAnswered() throws Exception { + testStatus("answered", CallStatus.ANSWERED); + } + + @Test + public void testStatusMachine() throws Exception { + testStatus("machine", CallStatus.MACHINE); + } + + @Test + public void testStatusCompleted() throws Exception { + testStatus("completed", CallStatus.COMPLETED); + } + + @Test + public void testStatusTimeout() throws Exception { + testStatus("timeout", CallStatus.TIMEOUT); + } + + @Test + public void testStatusFailed() throws Exception { + testStatus("failed", CallStatus.FAILED); + } + @Test + public void testStatusRejected() throws Exception { + testStatus("rejected", CallStatus.REJECTED); + } + + @Test + public void testStatusBusy() throws Exception { + testStatus("busy", CallStatus.BUSY); + } + + @Test + public void testStatusCancelled() throws Exception { + testStatus("cancelled", CallStatus.CANCELLED); + } + public void testStatus(String value, CallStatus expectedValue) throws Exception { + CallInfo record = new ObjectMapper().readValue(jsonWithPlaceholder.replaceFirst("PLACEHOLDER", value), + CallInfo.class); + assertEquals(record.getStatus(), expectedValue); } @Test @@ -100,4 +181,4 @@ public void testToString() throws Exception { "", record.toString()); } -} \ No newline at end of file +} diff --git a/src/test/java/com/nexmo/client/voice/endpoints/CreateCallMethodTest.java b/src/test/java/com/nexmo/client/voice/endpoints/CreateCallMethodTest.java index 2511ec95c..931254d3b 100644 --- a/src/test/java/com/nexmo/client/voice/endpoints/CreateCallMethodTest.java +++ b/src/test/java/com/nexmo/client/voice/endpoints/CreateCallMethodTest.java @@ -45,7 +45,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nexmo.client.HttpWrapper; import com.nexmo.client.voice.Call; import com.nexmo.client.voice.CallDirection; import com.nexmo.client.voice.CallEvent; @@ -64,6 +63,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; +import static com.nexmo.client.TestUtils.test429; import static org.junit.Assert.assertEquals; public class CreateCallMethodTest { @@ -118,4 +118,9 @@ public void testParseResponse() throws Exception { assertEquals(CallStatus.STARTED, callEvent.getStatus()); assertEquals(CallDirection.OUTBOUND, callEvent.getDirection()); } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new CreateCallMethod(null)); + } } diff --git a/src/test/java/com/nexmo/client/voice/endpoints/ListCallsMethodTest.java b/src/test/java/com/nexmo/client/voice/endpoints/ListCallsMethodTest.java index 3ca1ddfdd..762b8188c 100644 --- a/src/test/java/com/nexmo/client/voice/endpoints/ListCallsMethodTest.java +++ b/src/test/java/com/nexmo/client/voice/endpoints/ListCallsMethodTest.java @@ -40,7 +40,10 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; -import static org.junit.Assert.*; +import static com.nexmo.client.TestUtils.test429; +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; public class ListCallsMethodTest { private static final Log LOG = LogFactory.getLog(ListCallsMethodTest.class); @@ -177,4 +180,9 @@ public void testBadUriThrowsException() throws Exception { // This is expected } } + + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new ListCallsMethod(null)); + } } diff --git a/src/test/java/com/nexmo/client/voice/endpoints/ModifyCallMethodTest.java b/src/test/java/com/nexmo/client/voice/endpoints/ModifyCallMethodTest.java index b99913344..c8cb19367 100644 --- a/src/test/java/com/nexmo/client/voice/endpoints/ModifyCallMethodTest.java +++ b/src/test/java/com/nexmo/client/voice/endpoints/ModifyCallMethodTest.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.nexmo.client.HttpWrapper; import com.nexmo.client.voice.CallModifier; +import com.nexmo.client.voice.ModifyCallAction; import com.nexmo.client.voice.ModifyCallResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,6 +39,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.net.URI; import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; @@ -51,7 +53,7 @@ public void makeRequest() throws Exception { ModifyCallMethod methodUnderTest = new ModifyCallMethod(httpWrapper); RequestBuilder request = methodUnderTest.makeRequest( - new CallModifier("abc-123", "hangup") + new CallModifier("abc-123", ModifyCallAction.HANGUP) ); assertEquals("PUT", request.getMethod()); @@ -59,10 +61,77 @@ public void makeRequest() throws Exception { ObjectMapper objectMapper = new ObjectMapper(); JsonNode node = objectMapper.readValue(request.getEntity().getContent(), JsonNode.class); - LOG.info(request.getEntity().getContent()); assertEquals("hangup", node.get("action").asText()); } + @Test + public void earmuffRequest() throws Exception { + HttpWrapper httpWrapper = new HttpWrapper(); + ModifyCallMethod methodUnderTest = new ModifyCallMethod(httpWrapper); + + RequestBuilder request = methodUnderTest.makeRequest( + new CallModifier("abc-123", ModifyCallAction.EARMUFF) + ); + + assertEquals("PUT", request.getMethod()); + assertEquals("application/json", request.getFirstHeader("Content-Type").getValue()); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(request.getEntity().getContent(), JsonNode.class); + assertEquals("earmuff", node.get("action").asText()); + } + + @Test + public void unearmuffRequest() throws Exception { + HttpWrapper httpWrapper = new HttpWrapper(); + ModifyCallMethod methodUnderTest = new ModifyCallMethod(httpWrapper); + + RequestBuilder request = methodUnderTest.makeRequest( + new CallModifier("abc-123", ModifyCallAction.UNEARMUFF) + ); + + assertEquals("PUT", request.getMethod()); + assertEquals("application/json", request.getFirstHeader("Content-Type").getValue()); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(request.getEntity().getContent(), JsonNode.class); + assertEquals("unearmuff", node.get("action").asText()); + } + + @Test + public void muteRequest() throws Exception { + HttpWrapper httpWrapper = new HttpWrapper(); + ModifyCallMethod methodUnderTest = new ModifyCallMethod(httpWrapper); + + RequestBuilder request = methodUnderTest.makeRequest( + new CallModifier("abc-123", ModifyCallAction.MUTE) + ); + + assertEquals("PUT", request.getMethod()); + assertEquals("application/json", request.getFirstHeader("Content-Type").getValue()); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(request.getEntity().getContent(), JsonNode.class); + assertEquals("mute", node.get("action").asText()); + } + + @Test + public void unmuteRequest() throws Exception { + HttpWrapper httpWrapper = new HttpWrapper(); + ModifyCallMethod methodUnderTest = new ModifyCallMethod(httpWrapper); + + RequestBuilder request = methodUnderTest.makeRequest( + new CallModifier("abc-123", ModifyCallAction.UNMUTE) + ); + + assertEquals("PUT", request.getMethod()); + assertEquals("application/json", request.getFirstHeader("Content-Type").getValue()); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readValue(request.getEntity().getContent(), JsonNode.class); + assertEquals("unmute", node.get("action").asText()); + } + @Test public void parseResponse() throws Exception { HttpWrapper wrapper = new HttpWrapper(); @@ -81,4 +150,14 @@ public void parseResponse() throws Exception { ModifyCallResponse response = methodUnderTest.parseResponse(stubResponse); assertEquals("Received", response.getMessage()); } + + @Test + public void testSetUri() throws Exception { + ModifyCallMethod methodUnderTest = new ModifyCallMethod(null); + methodUnderTest.setUri("https://example.com/dummy/"); + RequestBuilder req = methodUnderTest.makeRequest( + new CallModifier("uuid-1234", ModifyCallAction.HANGUP) + ); + assertEquals(new URI("https://example.com/dummy/uuid-1234"), req.getUri()); + } } diff --git a/src/test/java/com/nexmo/client/voice/endpoints/ReadCallMethodTest.java b/src/test/java/com/nexmo/client/voice/endpoints/ReadCallMethodTest.java index 05f8c1aa7..1cbc22502 100644 --- a/src/test/java/com/nexmo/client/voice/endpoints/ReadCallMethodTest.java +++ b/src/test/java/com/nexmo/client/voice/endpoints/ReadCallMethodTest.java @@ -25,18 +25,11 @@ import com.nexmo.client.auth.JWTAuthMethod; import com.nexmo.client.voice.CallInfo; import org.apache.http.HttpResponse; -import org.apache.http.ProtocolVersion; import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.message.BasicHttpResponse; -import org.apache.http.message.BasicStatusLine; import org.junit.Before; import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; - +import static com.nexmo.client.TestUtils.test429; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -98,4 +91,8 @@ public void testBaseUri() throws Exception { } + @Test + public void testRequestThrottleResponse() throws Exception { + test429(new ReadCallMethod(null)); + } }