Skip to content

Commit 9e897d1

Browse files
SMadanijeffswartz
andauthored
Prepare v4.10.0 release (#240)
* Minor fixes in build.gradle * Added support for MultiBroadcastTag and MultiArchiveTag (#226) * Added multiArchiveTag * Added multiBroadcastTag * Updated docs * Removed getMulti*Tag from responses * Revert "Removed getMulti*Tag from responses" This reverts commit 6e7f123. * Docs edits re multiArchive/BroadcastTag. Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com> * Add Experience Composer API (#227) * Added startRender * Added listRenders * Deserialize listRenders response to native List * Added stopRender & getRender * Use enum for Render status * Improved RenderProperties * Experience composer docs edits ... And other docs corrections Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com> * Bump dependency versions * Improved release process. bump2version is now manual, but release to Nexus is fully automated. * Ensure version is passed in bumpversion.sh * Bumped dependencies (including WireMock) * Bump version: v4.8.0 → v4.8.1 * Update copyright year * Use wiremock-jre8 * Boost coverage * Boost coverage * Disable codecov temporarily * Revert "Disable codecov temporarily" This reverts commit 613bff0. * Add Audio Streamer (lite) API endpoint (#215) * Added Audio Streamer (lite) endpoint * Don't include headers or streams if empty in connect request * Renamed Connect for clarity * Addressed PR comments * Fixed failing test * URI in AudioStreamerConnectionProperties constructor * Docs edits * Bumped dependencies (notably WireMock to 2.x) * Bumped dependencies * Bump dependency versions (#233) Improved release process, bumped dependency versions (including WireMock), slightly improved test coverage, updated copyright year, merged main, ready for release v4.8.1. * Renamed to Audio Connector * Bumped dependencies * Added audio connector to README * Minor docs edits --------- Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com> * Bump version: v4.8.1 → v4.9.0 * Minor docs edit * Enable custom User-Agent (#238) * Add end-to-end encryption support (#237) * Added e2ee support * Added validation for SessionProperties * Only include e2ee if true * Update SessionProperties javadoc Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com> * Minor docs edit --------- Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com> * Bump jackson version * Bump version: v4.9.0 → v4.10.0 --------- Co-authored-by: Jeff Swartz <jeff.swartz@vonage.com>
1 parent 74abd63 commit 9e897d1

File tree

10 files changed

+206
-58
lines changed

10 files changed

+206
-58
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[bumpversion]
22
commit = True
33
tag = False
4-
current_version = v4.9.0
4+
current_version = v4.10.0
55
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<build>\d+))?
66
serialize =
77
{major}.{minor}.{patch}-{release}{build}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ When you use Maven as your build tool, you can manage dependencies in the `pom.x
3434
<dependency>
3535
<groupId>com.tokbox</groupId>
3636
<artifactId>opentok-server-sdk</artifactId>
37-
<version>4.9.0</version>
37+
<version>4.10.0</version>
3838
</dependency>
3939
```
4040

@@ -44,7 +44,7 @@ When you use Gradle as your build tool, you can manage dependencies in the `buil
4444

4545
```groovy
4646
dependencies {
47-
compile group: 'com.tokbox', name: 'opentok-server-sdk', version: '4.9.0'
47+
compile group: 'com.tokbox', name: 'opentok-server-sdk', version: '4.10.0'
4848
}
4949
```
5050

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111

1212
group = 'com.tokbox'
1313
archivesBaseName = 'opentok-server-sdk'
14-
version = '4.9.0'
14+
version = '4.10.0'
1515
sourceCompatibility = "1.8"
1616
targetCompatibility = "1.8"
1717

@@ -27,7 +27,7 @@ dependencies {
2727
implementation 'commons-lang:commons-lang:2.6'
2828
implementation 'commons-validator:commons-validator:1.7'
2929
implementation 'org.asynchttpclient:async-http-client:2.12.3'
30-
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
30+
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
3131
implementation 'commons-codec:commons-codec:1.15'
3232
implementation 'org.bitbucket.b_c:jose4j:0.9.3'
3333
implementation 'io.netty:netty-handler:4.1.89.Final'

src/main/java/com/opentok/OpenTok.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.fasterxml.jackson.databind.JsonNode;
1212
import com.fasterxml.jackson.databind.ObjectMapper;
1313
import com.fasterxml.jackson.databind.ObjectReader;
14+
import com.opentok.constants.DefaultUserAgent;
1415
import com.opentok.exception.InvalidArgumentException;
1516
import com.opentok.exception.OpenTokException;
1617
import com.opentok.exception.RequestException;
@@ -63,9 +64,7 @@ public class OpenTok {
6364
* @param apiSecret Your OpenTok API secret. (See your <a href="https://tokbox.com/account">Vonage Video API account page</a>.)
6465
*/
6566
public OpenTok(int apiKey, String apiSecret) {
66-
this.apiKey = apiKey;
67-
this.apiSecret = apiSecret.trim();
68-
this.client = new HttpClient.Builder(apiKey, apiSecret).build();
67+
this(apiKey, apiSecret, new HttpClient.Builder(apiKey, apiSecret).build());
6968
}
7069

7170
private OpenTok(int apiKey, String apiSecret, HttpClient httpClient) {
@@ -243,7 +242,7 @@ public String generateToken(String sessionId) throws OpenTokException {
243242
*/
244243
public Session createSession(SessionProperties properties) throws OpenTokException {
245244
final SessionProperties _properties = properties != null ? properties : new SessionProperties.Builder().build();
246-
final Map<String, Collection<String>> params = _properties.toMap();
245+
final Map<String, List<String>> params = _properties.toMap();
247246
final String response = client.createSession(params);
248247

249248
try {
@@ -991,6 +990,7 @@ public static class Builder {
991990
private int apiKey;
992991
private String apiSecret;
993992
private String apiUrl;
993+
private String appendUserAgent;
994994
private Proxy proxy;
995995
private ProxyAuthScheme proxyAuthScheme;
996996
private String principal;
@@ -1045,6 +1045,18 @@ public Builder proxy(Proxy proxy, ProxyAuthScheme proxyAuthScheme, String princi
10451045
return this;
10461046
}
10471047

1048+
/**
1049+
* Append a custom string to the client's User-Agent. This is to enable tracking for custom integrations.
1050+
*
1051+
* @param appendUserAgent The string to append to the user agent.
1052+
*
1053+
* @return This Builder with the additional user agent string.
1054+
*/
1055+
public Builder appendToUserAgent(String appendUserAgent) {
1056+
this.appendUserAgent = appendUserAgent;
1057+
return this;
1058+
}
1059+
10481060
/**
10491061
* Builds the OpenTok object with the settings provided to this
10501062
* Builder object.
@@ -1063,6 +1075,9 @@ public OpenTok build() {
10631075
if (requestTimeout != 0) {
10641076
clientBuilder.requestTimeoutMS(requestTimeout);
10651077
}
1078+
if (appendUserAgent != null && !appendUserAgent.trim().isEmpty()) {
1079+
clientBuilder.userAgent(DefaultUserAgent.DEFAULT_USER_AGENT+" "+appendUserAgent);
1080+
}
10661081

10671082
return new OpenTok(apiKey, apiSecret, clientBuilder.build());
10681083
}

src/main/java/com/opentok/Session.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,13 @@
2727
* to get the session ID.
2828
*/
2929
public class Session {
30-
3130
private String sessionId;
3231
private int apiKey;
3332
private String apiSecret;
3433
private SessionProperties properties;
3534

3635
protected Session(String sessionId, int apiKey, String apiSecret) {
37-
this.sessionId = sessionId;
38-
this.apiKey = apiKey;
39-
this.apiSecret = apiSecret;
40-
this.properties = new SessionProperties.Builder().build();
36+
this(sessionId, apiKey, apiSecret, new SessionProperties.Builder().build());
4137
}
4238

4339
protected Session(String sessionId, int apiKey, String apiSecret, SessionProperties properties) {
@@ -83,7 +79,6 @@ public SessionProperties getProperties() {
8379
* @see #generateToken(TokenOptions tokenOptions)
8480
*/
8581
public String generateToken() throws OpenTokException {
86-
// NOTE: maybe there should be a static object for the defaultTokenOptions?
8782
return this.generateToken(new TokenOptions.Builder().build());
8883
}
8984

src/main/java/com/opentok/SessionProperties.java

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
import com.opentok.exception.InvalidArgumentException;
1111
import org.apache.commons.validator.routines.InetAddressValidator;
1212

13-
import java.util.ArrayList;
14-
import java.util.Collection;
15-
import java.util.HashMap;
16-
import java.util.Map;
13+
import java.util.*;
1714

1815

1916
/**
@@ -23,16 +20,16 @@
2320
* @see OpenTok#createSession(com.opentok.SessionProperties properties)
2421
*/
2522
public class SessionProperties {
26-
27-
2823
private String location;
2924
private MediaMode mediaMode;
3025
private ArchiveMode archiveMode;
26+
private boolean e2ee;
3127

3228
private SessionProperties(Builder builder) {
3329
this.location = builder.location;
3430
this.mediaMode = builder.mediaMode;
3531
this.archiveMode = builder.archiveMode;
32+
this.e2ee = builder.e2ee;
3633
}
3734

3835
/**
@@ -41,10 +38,10 @@ private SessionProperties(Builder builder) {
4138
* @see SessionProperties
4239
*/
4340
public static class Builder {
44-
private String location = null;
41+
private String location;
4542
private MediaMode mediaMode = MediaMode.RELAYED;
4643
private ArchiveMode archiveMode = ArchiveMode.MANUAL;
47-
44+
private boolean e2ee = false;
4845

4946
/**
5047
* Call this method to set an IP address that the OpenTok servers will use to
@@ -108,7 +105,7 @@ public Builder mediaMode(MediaMode mediaMode) {
108105
/**
109106
* Call this method to determine whether the session will be automatically archived (<code>ArchiveMode.ALWAYS</code>)
110107
* or not (<code>ArchiveMode.MANUAL</code>).
111-
*
108+
* <p>
112109
* Using an always archived session also requires the routed media mode (<code>MediaMode.ROUTED</code>).
113110
*
114111
* @param archiveMode The Archive mode.
@@ -120,19 +117,43 @@ public Builder archiveMode(ArchiveMode archiveMode) {
120117
return this;
121118
}
122119

120+
/**
121+
* Enables <a href="https://tokbox.com/developer/guides/end-to-end-encryption">end-to-end encryption</a> for a routed session.
122+
* You must also set {@link #mediaMode(MediaMode)} to {@linkplain MediaMode#ROUTED} when
123+
* calling this method.
124+
*
125+
* @return The SessionProperties.Builder object with the e2ee property set to {@code true}.
126+
*/
127+
public Builder endToEndEncryption() {
128+
this.e2ee = true;
129+
return this;
130+
}
131+
123132
/**
124133
* Builds the SessionProperties object.
125134
*
126135
* @return The SessionProperties object.
127136
*/
128137
public SessionProperties build() {
129-
// Would throw in this case, but would introduce a backwards incompatible change.
130-
//if (this.archiveMode == ArchiveMode.ALWAYS && this.mediaMode != MediaMode.ROUTED) {
131-
// throw new InvalidArgumentException("A session with always archive mode must also have the routed media mode.");
132-
//}
138+
if (this.archiveMode == ArchiveMode.ALWAYS && this.mediaMode != MediaMode.ROUTED) {
139+
throw new IllegalStateException(
140+
"A session with ALWAYS archive mode must also have the ROUTED media mode."
141+
);
142+
}
143+
if (e2ee && mediaMode != MediaMode.ROUTED) {
144+
throw new IllegalStateException(
145+
"A session with RELAYED media mode cannot have end-to-end encryption enabled."
146+
);
147+
}
148+
if (e2ee && archiveMode == ArchiveMode.ALWAYS) {
149+
throw new IllegalStateException(
150+
"A session with ALWAYS archive mode cannot have end-to-end encryption enabled."
151+
);
152+
}
133153
return new SessionProperties(this);
134154
}
135155
}
156+
136157
/**
137158
* The location hint IP address. See {@link SessionProperties.Builder#location(String location)}.
138159
*/
@@ -158,25 +179,43 @@ public ArchiveMode archiveMode() {
158179
return archiveMode;
159180
}
160181

182+
/**
183+
* Defines whether the session will use
184+
* <a href="https://tokbox.com/developer/guides/end-to-end-encryption">end-to-end encryption</a>.
185+
* See {@link com.opentok.SessionProperties.Builder#endToEndEncryption()}.
186+
*
187+
*
188+
* @return {@code true} if end-to-end encryption is enabled, {@code false} otherwise.
189+
*/
190+
public boolean isEndToEndEncrypted() {
191+
return e2ee;
192+
}
193+
161194
/**
162195
* Returns the session properties as a Map.
163196
*/
164-
public Map<String, Collection<String>> toMap() {
165-
Map<String, Collection<String>> params = new HashMap<>();
197+
public Map<String, List<String>> toMap() {
198+
Map<String, List<String>> params = new HashMap<>();
166199
if (null != location) {
167-
ArrayList<String> valueList = new ArrayList<>();
200+
ArrayList<String> valueList = new ArrayList<>(1);
168201
valueList.add(location);
169202
params.put("location", valueList);
170203
}
171204

172-
ArrayList<String> mediaModeValueList = new ArrayList<>();
205+
ArrayList<String> mediaModeValueList = new ArrayList<>(1);
173206
mediaModeValueList.add(mediaMode.toString());
174207
params.put("p2p.preference", mediaModeValueList);
175208

176-
ArrayList<String> archiveModeValueList = new ArrayList<>();
209+
ArrayList<String> archiveModeValueList = new ArrayList<>(1);
177210
archiveModeValueList.add(archiveMode.toString());
178211
params.put("archiveMode", archiveModeValueList);
179212

213+
if (e2ee) {
214+
ArrayList<String> e2eeValueList = new ArrayList<>(1);
215+
e2eeValueList.add("" + e2ee);
216+
params.put("e2ee", e2eeValueList);
217+
}
218+
180219
return params;
181220
}
182221

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* OpenTok Java SDK
3+
* Copyright (C) 2023 Vonage.
4+
* http://www.tokbox.com
5+
*
6+
* Licensed under The MIT License (MIT). See LICENSE file for more information.
7+
*/
8+
package com.opentok.constants;
9+
10+
public class DefaultUserAgent {
11+
public static final String DEFAULT_USER_AGENT =
12+
"Opentok-Java-SDK/"+Version.VERSION+" JRE/"+System.getProperty("java.version");
13+
}

src/main/java/com/opentok/constants/Version.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
package com.opentok.constants;
99

1010
public class Version {
11-
public static final String VERSION = "4.9.0";
11+
public static final String VERSION = "4.10.0";
1212
}

src/main/java/com/opentok/util/HttpClient.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.fasterxml.jackson.databind.node.ObjectNode;
1717
import com.opentok.*;
1818
import com.opentok.constants.DefaultApiUrl;
19+
import com.opentok.constants.DefaultUserAgent;
1920
import com.opentok.constants.Version;
2021
import com.opentok.exception.InvalidArgumentException;
2122
import com.opentok.exception.OpenTokException;
@@ -38,7 +39,6 @@
3839
import java.util.concurrent.Future;
3940

4041
public class HttpClient extends DefaultAsyncHttpClient {
41-
4242
private final String apiUrl;
4343
private final int apiKey;
4444

@@ -48,17 +48,9 @@ private HttpClient(Builder builder) {
4848
this.apiUrl = builder.apiUrl;
4949
}
5050

51-
public String createSession(Map<String, Collection<String>> params) throws RequestException {
52-
Map<String, List<String>> paramsWithList = null;
53-
if (params != null) {
54-
paramsWithList = new HashMap<>();
55-
for (Entry<String, Collection<String>> entry : params.entrySet()) {
56-
paramsWithList.put(entry.getKey(), new ArrayList<>(entry.getValue()));
57-
}
58-
}
59-
51+
public String createSession(Map<String, List<String>> params) throws RequestException {
6052
Future<Response> request = this.preparePost(this.apiUrl + "/session/create")
61-
.setFormParams(paramsWithList)
53+
.setFormParams(params)
6254
.setHeader("Accept", "application/json") // XML version is deprecated
6355
.execute();
6456

@@ -1303,6 +1295,7 @@ public static class Builder {
13031295
private String principal;
13041296
private String password;
13051297
private String apiUrl;
1298+
private String userAgent = DefaultUserAgent.DEFAULT_USER_AGENT;
13061299
private AsyncHttpClientConfig config;
13071300
private int requestTimeoutMS;
13081301

@@ -1340,18 +1333,29 @@ public Builder requestTimeoutMS(int requestTimeoutMS) {
13401333
return this;
13411334
}
13421335

1336+
/**
1337+
* Sets the user agent to a custom value.
1338+
*
1339+
* @param userAgent The user agent.
1340+
*
1341+
* @return This Builder with user agent string.
1342+
*/
1343+
public Builder userAgent(String userAgent) {
1344+
this.userAgent = userAgent;
1345+
return this;
1346+
}
1347+
13431348
public HttpClient build() {
13441349
DefaultAsyncHttpClientConfig.Builder configBuilder = new DefaultAsyncHttpClientConfig.Builder()
1345-
.setUserAgent("Opentok-Java-SDK/" + Version.VERSION + " JRE/" + System.getProperty("java.version"))
1350+
.setUserAgent(userAgent)
13461351
.addRequestFilter(new TokenAuthRequestFilter(apiKey, apiSecret));
1352+
13471353
if (apiUrl == null) {
13481354
apiUrl = DefaultApiUrl.DEFAULT_API_URI;
13491355
}
1350-
13511356
if (proxy != null) {
13521357
configBuilder.setProxyServer(createProxyServer(proxy, proxyAuthScheme, principal, password));
13531358
}
1354-
13551359
if (requestTimeoutMS != 0) {
13561360
configBuilder.setRequestTimeout(requestTimeoutMS);
13571361
}

0 commit comments

Comments
 (0)