diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 21aea09..fcff8b7 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = True tag = False -current_version = v4.14.0 +current_version = v4.14.1 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P[a-z]+)(?P\d+))? serialize = {major}.{minor}.{patch}-{release}{build} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c27ceca..9ac9957 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build Java CI +name: Build & Test on: push: branches: @@ -81,4 +81,4 @@ jobs: run: ./gradlew build - name: Run Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 diff --git a/README.md b/README.md index 5e785c4..6eb1dd2 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ When you use Maven as your build tool, you can manage dependencies in the `pom.x com.tokbox opentok-server-sdk - 4.14.0 + 4.14.1 ``` @@ -55,7 +55,7 @@ When you use Gradle as your build tool, you can manage dependencies in the `buil ```groovy dependencies { - compile group: 'com.tokbox', name: 'opentok-server-sdk', version: '4.14.0' + compile group: 'com.tokbox', name: 'opentok-server-sdk', version: '4.14.1' } ``` diff --git a/build.gradle b/build.gradle index 0bd3cd8..33c68b1 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { group = 'com.tokbox' archivesBaseName = 'opentok-server-sdk' -version = '4.14.0' +version = '4.14.1' ext.githubPath = "opentok/$archivesBaseName" @@ -21,15 +21,13 @@ repositories { dependencies { testImplementation 'junit:junit:4.13.2' - testImplementation 'org.wiremock:wiremock:3.5.4' - testImplementation 'org.xmlunit:xmlunit-core:2.10.0' - testImplementation 'net.minidev:json-smart:2.5.1' - testImplementation 'com.google.guava:guava:33.2.0-jre' + testImplementation 'org.wiremock:wiremock:3.6.0' + testImplementation 'com.google.guava:guava:33.2.1-jre' implementation 'commons-lang:commons-lang:2.6' implementation 'commons-codec:commons-codec:1.17.0' - implementation 'io.netty:netty-codec-http:4.1.109.Final' - implementation 'io.netty:netty-handler:4.1.109.Final' + implementation 'io.netty:netty-codec-http:4.1.111.Final' + implementation 'io.netty:netty-handler:4.1.111.Final' implementation 'org.asynchttpclient:async-http-client:2.12.3' implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1' implementation 'org.bitbucket.b_c:jose4j:0.9.6' diff --git a/src/main/java/com/opentok/constants/Version.java b/src/main/java/com/opentok/constants/Version.java index 9b1d746..de83fe3 100644 --- a/src/main/java/com/opentok/constants/Version.java +++ b/src/main/java/com/opentok/constants/Version.java @@ -8,5 +8,5 @@ package com.opentok.constants; public class Version { - public static final String VERSION = "4.14.0"; + public static final String VERSION = "4.14.1"; } diff --git a/src/main/java/com/opentok/util/HttpClient.java b/src/main/java/com/opentok/util/HttpClient.java index 02b3773..750a8c0 100644 --- a/src/main/java/com/opentok/util/HttpClient.java +++ b/src/main/java/com/opentok/util/HttpClient.java @@ -91,7 +91,7 @@ public String signal(String sessionId, String connectionId, SignalProperties pro case 204: return response.getResponseBody(); case 400: - throw new RequestException("Could not send a signal. One of the signal properties is invalid."); + throw new RequestException("Could not send a signal: "+response.getResponseBody()); case 403: throw new RequestException("Could not send a signal. The request was not authorized."); case 404: @@ -227,7 +227,7 @@ public String startArchive(String sessionId, ArchiveProperties properties) throw case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not start an OpenTok Archive. A bad request, check input archive properties like resolution etc."); + throw new RequestException("Could not start an OpenTok Archive: "+response.getResponseBody()); case 403: throw new RequestException("Could not start an OpenTok Archive. The request was not authorized."); case 404: @@ -259,9 +259,7 @@ public String stopArchive(String archiveId) throws RequestException { case 200: return response.getResponseBody(); case 400: - // NOTE: the REST api spec talks about sessionId and action, both of which aren't required. - // see: https://github.com/opentok/OpenTok-2.0-archiving-samples/blob/master/REST-API.md#stop_archive - throw new RequestException("Could not stop an OpenTok Archive."); + throw new RequestException("Could not stop an OpenTok Archive: "+response.getResponseBody()); case 403: throw new RequestException("Could not stop an OpenTok Archive. The request was not authorized."); case 404: @@ -327,7 +325,7 @@ else if (addStream != null && !addStream.isEmpty()) { try { requestBody = new ObjectMapper().writeValueAsString(requestJson); } catch (JsonProcessingException e) { - throw new OpenTokException("Could not patch opentok archive. The JSON body encoding failed"); + throw new OpenTokException("Could not patch OpenTok archive. The JSON body encoding failed"); } Future request = this.preparePatch(url) @@ -341,22 +339,22 @@ else if (addStream != null && !addStream.isEmpty()) { case 204: return response.getResponseBody(); case 400: - throw new RequestException("Could not patch opentok archive. A invalid request. Check input properties."); + throw new RequestException("Could not patch OpenTok archive: "+response.getResponseBody()); case 404: - throw new RequestException("Could not patch opentok archive. Archive or stream not found."); + throw new RequestException("Could not patch OpenTok archive. Archive or stream not found."); case 405: - throw new RequestException("Could not patch opentok archive. Stream mode not supported for patching."); + throw new RequestException("Could not patch OpenTok archive. Stream mode not supported for patching."); case 403: - throw new RequestException("Could not patch opentok archive. The request was unauthorized."); + throw new RequestException("Could not patch OpenTok archive. The request was unauthorized."); case 500: - throw new RequestException("Could not patch opentok archive. A server error occurred"); + throw new RequestException("Could not patch OpenTok archive. A server error occurred"); default: - throw new RequestException("Could not patch opentok archive. The server response was invalid. Response code: " + + throw new RequestException("Could not patch OpenTok archive. The server response was invalid. Response code: " + response.getStatusCode()); } } catch (ExecutionException | InterruptedException e) { - throw new RequestException("Could not patch an opentok archive.", e); + throw new RequestException("Could not patch an OpenTok archive.", e); } } @@ -411,7 +409,7 @@ public String setArchiveLayout(String archiveId, ArchiveProperties properties) t case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not set the layout. Either an invalid JSON or an invalid layout options."); + throw new RequestException("Could not set the layout: "+response.getResponseBody()); case 403: throw new RequestException("Could not set the layout. The request was not authorized."); case 500: @@ -467,7 +465,7 @@ public String setStreamLayouts(String sessionId, StreamListProperties properties case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not set the layout. Either an invalid JSON or an invalid layout options."); + throw new RequestException("Could not set the layout: "+response.getResponseBody()); case 403: throw new RequestException("Could not set the layout. The request was not authorized."); case 500: @@ -560,7 +558,7 @@ public String startBroadcast(String sessionId, BroadcastProperties properties) t case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not start an OpenTok Broadcast. A bad request, check input properties like resolution etc."); + throw new RequestException("Could not start an OpenTok Broadcast: "+response.getResponseBody()); case 403: throw new RequestException("Could not start an OpenTok Broadcast. The request was not authorized."); case 409: @@ -590,7 +588,7 @@ public String stopBroadcast(String broadcastId) throws OpenTokException { case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not start an OpenTok Broadcast. A bad request, check input properties like resolution etc."); + throw new RequestException("Could not start an OpenTok Broadcast: "+response.getResponseBody()); case 403: throw new RequestException("Could not start an OpenTok Broadcast. The request was not authorized."); case 404: @@ -620,7 +618,7 @@ public String getBroadcast(String broadcastId) throws OpenTokException { case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not get Broadcast stream information. A bad request, check input properties."); + throw new RequestException("Could not get Broadcast stream information: "+response.getResponseBody()); case 403: throw new RequestException("Could not get Broadcast stream information.. The request was not authorized."); case 404: @@ -641,10 +639,10 @@ public String patchBroadcast(String broadcastId, String addStream, String remove JsonNodeFactory nodeFactory = JsonNodeFactory.instance; ObjectNode requestJson = nodeFactory.objectNode(); - if (removeStream != null && !removeStream.equals("")) { + if (removeStream != null && !removeStream.isEmpty()) { requestJson.put("removeStream", removeStream); } - else if(addStream != null && !addStream.equals("")) { + else if(addStream != null && !addStream.isEmpty()) { requestJson.put("hasAudio", hasAudio); requestJson.put("hasVideo", hasVideo); requestJson.put("addStream", addStream); @@ -657,7 +655,7 @@ else if(addStream != null && !addStream.equals("")) { try { requestBody = new ObjectMapper().writeValueAsString(requestJson); } catch (JsonProcessingException e) { - throw new OpenTokException("Could not patch opentok archive. The JSON body encoding failed"); + throw new OpenTokException("Could not patch OpenTok archive. The JSON body encoding failed"); } Future request = this.preparePatch(url) @@ -670,22 +668,22 @@ else if(addStream != null && !addStream.equals("")) { case 204: return response.getResponseBody(); case 400: - throw new RequestException("Could not patch opentok broadcast. A invalid request. Check input properties."); + throw new RequestException("Could not patch OpenTok broadcast: "+response.getResponseBody()); case 404: - throw new RequestException("Could not patch opentok broadcast. Archive or stream not found."); + throw new RequestException("Could not patch OpenTok broadcast. Archive or stream not found."); case 405: - throw new RequestException("Could not patch opentok broadcast. Stream mode not supported for patching."); + throw new RequestException("Could not patch OpenTok broadcast. Stream mode not supported for patching."); case 403: - throw new RequestException("Could not patch opentok broadcast. The request was unauthorized."); + throw new RequestException("Could not patch OpenTok broadcast. The request was unauthorized."); case 500: - throw new RequestException("Could not patch opentok broadcast. A server error occurred"); + throw new RequestException("Could not patch OpenTok broadcast. A server error occurred"); default: - throw new RequestException("Could not patch opentok broadcast. The server response was invalid. Response code: " + + throw new RequestException("Could not patch OpenTok broadcast. The server response was invalid. Response code: " + response.getStatusCode()); } } catch (ExecutionException | InterruptedException e) { - throw new RequestException("Could not patch an opentok broadcast.", e); + throw new RequestException("Could not patch an OpenTok broadcast.", e); } } @@ -741,7 +739,7 @@ public String setBroadcastLayout(String broadcastId, BroadcastProperties propert case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not set the layout. Either an invalid JSON or an invalid layout options."); + throw new RequestException("Could not set the layout: "+response.getResponseBody()); case 403: throw new RequestException("Could not set the layout. The request was not authorized."); case 500: @@ -765,7 +763,7 @@ public String forceDisconnect(String sessionId, String connectionId) throws Open case 204: return response.getResponseBody(); case 400: - throw new RequestException("Could not force disconnect. One of the arguments — sessionId or connectionId — is invalid."); + throw new RequestException("Could not force disconnect: "+response.getResponseBody()); case 403: throw new RequestException("Could not force disconnect. You are not authorized to forceDisconnect, check your authentication credentials."); case 404: @@ -853,7 +851,7 @@ public String sipDial(String sessionId, String token, SipProperties props) throw case 200: return response.getResponseBody(); case 400: - throw new RequestException("Could not set the sip dial. Either an invalid sessionId or the custom header does not start with the X- prefix."); + throw new RequestException("Could not set the SIP dial. Either an invalid sessionId or the custom header does not start with the X- prefix."); case 403: throw new RequestException("Could not set the sip dial. The request was not authorized."); case 404: @@ -922,14 +920,11 @@ public String getStream(String sessionId, String streamId) throws RequestExcepti case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID. " - + "sessionId: " + sessionId + "streamId: " + streamId); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("Invalid OpenTok API key or JWT token."); - case 408: - throw new RequestException("You passed in an invalid stream ID." + - "streamId: " + streamId); + throw new RequestException("You passed in an invalid stream ID: " + streamId); case 500: throw new RequestException("OpenTok server error."); default: @@ -951,14 +946,11 @@ public String forceMuteStream(String sessionId, String streamId) throws RequestE case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request invalid session ID or invalid stream ID. " - + "sessionId: " + sessionId + "streamId: " + streamId); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("Invalid OpenTok API key or JWT token."); - case 408: - throw new RequestException("You passed in an invalid stream ID." + - "streamId: " + streamId); + throw new RequestException("You passed in an invalid stream ID: "+streamId); case 500: throw new RequestException("OpenTok server error."); default: @@ -983,7 +975,7 @@ public String forceMuteAllStream(String sessionId, MuteAllProperties properties) jGenerator.writeStartObject(); jGenerator.writeBooleanField("active", true); - jGenerator.writeFieldName("excudedStreamIds"); + jGenerator.writeFieldName("excludedStreamIds"); StringJoiner sj = new StringJoiner(","); properties.getExcludedStreamIds().forEach(e -> sj.add(doubleQuotes + e + doubleQuotes)); @@ -1007,8 +999,7 @@ public String forceMuteAllStream(String sessionId, MuteAllProperties properties) case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request invalid session ID or invalid stream ID. " - + "sessionId: " + sessionId); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("Invalid OpenTok API key or JWT token."); case 408: @@ -1054,8 +1045,7 @@ public String disableForceMute(String sessionId) throws OpenTokException { case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request invalid session ID or invalid stream ID. " - + "sessionId: " + sessionId); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("Invalid OpenTok API key or JWT token."); case 408: @@ -1083,7 +1073,7 @@ public String listStreams(String sessionId) throws RequestException { case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request. This response may indicate that data in your request data is invalid JSON. Or it may indicate that you do not pass in a session ID or you passed in an invalid stream ID"); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("You passed in an invalid OpenTok API key or JWT token"); case 408: @@ -1137,8 +1127,7 @@ public String connectAudioStream(String sessionId, String token, AudioConnectorP case 200: return response.getResponseBody(); case 400: - throw new RequestException("Invalid request invalid session ID or invalid stream ID. " - + "sessionId: " + sessionId); + throw new RequestException(response.getResponseBody()); case 403: throw new RequestException("Invalid OpenTok API key or JWT token."); case 409: diff --git a/src/test/java/com/opentok/test/OpenTokTest.java b/src/test/java/com/opentok/test/OpenTokTest.java index 1dd13e0..9ec71c8 100644 --- a/src/test/java/com/opentok/test/OpenTokTest.java +++ b/src/test/java/com/opentok/test/OpenTokTest.java @@ -2720,8 +2720,15 @@ public void testConnectAudioStreamErrors() throws OpenTokException { String uri = "ws://service.com/wsendpoint"; AudioConnectorProperties connectProperties = new AudioConnectorProperties.Builder(uri).build(); - stubFor(post(urlEqualTo(url)).willReturn(aResponse().withStatus(400))); - assertThrows(RequestException.class, () -> sdk.connectAudioStream(sessionId, apiSecret, connectProperties)); + String expected400Msg = "Oops! Something went wrong - bad request."; + stubFor(post(urlEqualTo(url)).willReturn(aResponse().withStatus(400).withBody(expected400Msg))); + try { + AudioConnector parsed = sdk.connectAudioStream(sessionId, apiSecret, connectProperties); + fail("Expected RequestException, but got "+parsed); + } + catch (RequestException ex) { + assertEquals(expected400Msg, ex.getMessage()); + } stubFor(post(urlEqualTo(url)).willReturn(aResponse().withStatus(403))); assertThrows(RequestException.class, () -> sdk.connectAudioStream(sessionId, apiSecret, connectProperties));