openvidu-server: remove deprecations and warnings

v2
pabloFuente 2025-11-11 16:37:11 +01:00
parent 3b35a8b264
commit 3353cd14e5
15 changed files with 213 additions and 127 deletions

View File

@ -86,17 +86,17 @@
the same as in the parent pom.xml nonetheless --> the same as in the parent pom.xml nonetheless -->
<version>2.0.17</version> <version>2.0.17</version>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>commons-validator</groupId> <groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId> <artifactId>commons-validator</artifactId>
<version>1.10.0</version> <version>1.10.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.14.1</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>

View File

@ -24,6 +24,7 @@ import com.google.gson.JsonObject;
* @deprecated Use {@link io.openvidu.java.client.ConnectionProperties * @deprecated Use {@link io.openvidu.java.client.ConnectionProperties
* ConnectionProperties} instead * ConnectionProperties} instead
*/ */
@Deprecated
public class TokenOptions { public class TokenOptions {
private OpenViduRole role; private OpenViduRole role;
@ -34,6 +35,7 @@ public class TokenOptions {
* @deprecated Use {@link io.openvidu.java.client.ConnectionProperties.Builder * @deprecated Use {@link io.openvidu.java.client.ConnectionProperties.Builder
* ConnectionProperties.Builder} instead * ConnectionProperties.Builder} instead
*/ */
@Deprecated
public static class Builder { public static class Builder {
private OpenViduRole role = OpenViduRole.PUBLISHER; private OpenViduRole role = OpenViduRole.PUBLISHER;

View File

@ -22,19 +22,16 @@ import java.io.IOException;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -678,8 +675,9 @@ public class OpenviduConfig {
if (coturnIp == null || this.coturnIp.isEmpty()) { if (coturnIp == null || this.coturnIp.isEmpty()) {
try { try {
this.coturnIp = new URL(this.getFinalUrl()).getHost(); URI finalUri = new URI(this.getFinalUrl());
} catch (MalformedURLException e) { this.coturnIp = finalUri.getHost();
} catch (URISyntaxException e) {
log.error("Can't get Domain name from OpenVidu public Url: " + e.getMessage()); log.error("Can't get Domain name from OpenVidu public Url: " + e.getMessage());
} }
} }
@ -945,7 +943,8 @@ public class OpenviduConfig {
} }
} }
protected Integer asOptionalIntegerBetweenRanges(String property, Range<Integer>... ranges) { @SafeVarargs
protected final Integer asOptionalIntegerBetweenRanges(String property, Range<Integer>... ranges) {
try { try {
String value = getValue(property); String value = getValue(property);
if (value == null || value.isEmpty()) { if (value == null || value.isEmpty()) {
@ -1087,12 +1086,17 @@ public class OpenviduConfig {
public URI checkWebsocketUri(String uri) throws Exception { public URI checkWebsocketUri(String uri) throws Exception {
try { try {
if (!StringUtils.startsWithAny(uri, "ws://", "wss://")) { if (!(uri.startsWith("ws://") || uri.startsWith("wss://"))) {
throw new Exception("WebSocket protocol not found"); throw new Exception("WebSocket protocol not found");
} }
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://"); String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
return new URL(parsedUri).toURI(); URI parsed = new URI(parsedUri);
} catch (Exception e) { String scheme = parsed.getScheme();
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
throw new Exception("Unsupported protocol " + scheme);
}
return parsed;
} catch (URISyntaxException e) {
throw new RuntimeException( throw new RuntimeException(
"URI '" + uri + "' has not a valid WebSocket endpoint format: " + e.getMessage()); "URI '" + uri + "' has not a valid WebSocket endpoint format: " + e.getMessage());
} }
@ -1100,8 +1104,14 @@ public class OpenviduConfig {
protected void checkUrl(String url) throws Exception { protected void checkUrl(String url) throws Exception {
try { try {
new URL(url).toURI(); URI uri = new URI(url);
} catch (MalformedURLException | URISyntaxException e) { if (uri.getScheme() == null || uri.getScheme().isEmpty()) {
throw new Exception("Missing URL scheme");
}
if (uri.getHost() == null || uri.getHost().isEmpty()) {
throw new Exception("Missing URL host");
}
} catch (URISyntaxException e) {
throw new Exception("String '" + url + "' has not a valid URL format: " + e.getMessage()); throw new Exception("String '" + url + "' has not a valid URL format: " + e.getMessage());
} }
} }
@ -1283,12 +1293,20 @@ public class OpenviduConfig {
if (RecordingLayout.CUSTOM.equals(recordingProperties.recordingLayout())) { if (RecordingLayout.CUSTOM.equals(recordingProperties.recordingLayout())) {
String layout = recordingProperties.customLayout(); String layout = recordingProperties.customLayout();
if (!layout.isEmpty()) { if (!layout.isEmpty()) {
URI layoutUri = null;
try { try {
URL url = new URL(layout); layoutUri = new URI(layout);
log.info("\"customLayout\" property has a URL format ({}). Using it to connect to custom layout", } catch (URISyntaxException e) {
url.toString()); layoutUri = null;
return processCustomLayoutUrlFormat(url, sessionId); }
} catch (MalformedURLException e) { boolean layoutIsAbsoluteUrl = layoutUri != null && layoutUri.getScheme() != null
&& layoutUri.getHost() != null;
if (layoutIsAbsoluteUrl) {
log.info(
"\"customLayout\" property has a URL format ({}). Using it to connect to custom layout",
layoutUri.toString());
return processCustomLayoutUrlFormat(layoutUri, sessionId);
}
String layoutPath = this.getOpenviduRecordingCustomLayout() + layout; String layoutPath = this.getOpenviduRecordingCustomLayout() + layout;
layoutPath = layoutPath.endsWith("/") ? layoutPath : (layoutPath + "/"); layoutPath = layoutPath.endsWith("/") ? layoutPath : (layoutPath + "/");
log.info( log.info(
@ -1309,7 +1327,6 @@ public class OpenviduConfig {
} }
} }
} }
}
boolean recordingComposedUrlDefined = this.getOpenViduRecordingComposedUrl() != null boolean recordingComposedUrlDefined = this.getOpenViduRecordingComposedUrl() != null
&& !this.getOpenViduRecordingComposedUrl().isEmpty(); && !this.getOpenViduRecordingComposedUrl().isEmpty();
@ -1340,8 +1357,12 @@ public class OpenviduConfig {
layout = recordingProperties.recordingLayout().name().toLowerCase().replaceAll("_", "-"); layout = recordingProperties.recordingLayout().name().toLowerCase().replaceAll("_", "-");
int port = startsWithHttp ? 80 : 443; int port = startsWithHttp ? 80 : 443;
try { try {
port = new URL(this.getFinalUrl()).getPort(); URI finalUri = new URI(this.getFinalUrl());
} catch (MalformedURLException e) { int uriPort = finalUri.getPort();
if (uriPort != -1) {
port = uriPort;
}
} catch (URISyntaxException e) {
log.error(e.getMessage()); log.error(e.getMessage());
} }
String defaultPathForDefaultLayout = recordingComposedUrlDefined ? "" String defaultPathForDefaultLayout = recordingComposedUrlDefined ? ""
@ -1354,53 +1375,63 @@ public class OpenviduConfig {
return finalUrl; return finalUrl;
} }
private String processCustomLayoutUrlFormat(URL url, String shortSessionId) { private String processCustomLayoutUrlFormat(URI url, String shortSessionId) {
String finalUrl = url.getProtocol() + "://" + url.getAuthority(); StringBuilder finalUrl = new StringBuilder();
if (!url.getPath().isEmpty()) { String scheme = url.getScheme();
finalUrl += url.getPath(); if (scheme != null && !scheme.isEmpty()) {
finalUrl.append(scheme).append("://");
} }
finalUrl = finalUrl.endsWith("/") ? finalUrl.substring(0, finalUrl.length() - 1) : finalUrl; String authority = url.getRawAuthority();
if (url.getQuery() != null) { if (authority != null) {
URI uri; finalUrl.append(authority);
try {
uri = url.toURI();
finalUrl += "?";
} catch (URISyntaxException e) {
String error = "\"customLayout\" property has URL format and query params (" + url.toString()
+ "), but does not comply with RFC2396 URI format";
log.error(error);
throw new OpenViduException(Code.RECORDING_PATH_NOT_VALID, error);
} }
List<NameValuePair> params = URLEncodedUtils.parse(uri, Charset.forName("UTF-8")); String path = url.getRawPath();
Iterator<NameValuePair> it = params.iterator(); if (path != null && !path.isEmpty()) {
finalUrl.append(path);
}
int length = finalUrl.length();
if (length > 0 && finalUrl.charAt(length - 1) == '/') {
finalUrl.deleteCharAt(length - 1);
}
String query = url.getRawQuery();
if (query != null) {
finalUrl.append('?');
List<NameValuePair> params = URLEncodedUtils.parse(url, StandardCharsets.UTF_8);
boolean hasSessionId = false; boolean hasSessionId = false;
boolean hasSecret = false; boolean hasSecret = false;
while (it.hasNext()) { for (int i = 0; i < params.size(); i++) {
NameValuePair param = it.next(); NameValuePair param = params.get(i);
finalUrl += param.getName() + "=" + param.getValue(); finalUrl.append(param.getName()).append('=').append(param.getValue());
if (it.hasNext()) { if (i < params.size() - 1) {
finalUrl += "&"; finalUrl.append('&');
} }
if (!hasSessionId && "sessionId".equals(param.getName())) {
hasSessionId = true;
}
if (!hasSecret && "secret".equals(param.getName())) {
hasSecret = true;
}
}
boolean hasAppendedParams = !params.isEmpty();
if (!hasSessionId) { if (!hasSessionId) {
hasSessionId = param.getName().equals("sessionId"); if (hasAppendedParams) {
finalUrl.append('&');
}
finalUrl.append("sessionId=").append(shortSessionId);
hasAppendedParams = true;
} }
if (!hasSecret) { if (!hasSecret) {
hasSecret = param.getName().equals("secret"); if (hasAppendedParams) {
finalUrl.append('&');
}
finalUrl.append("secret=").append(this.getOpenViduSecret());
} }
} }
if (!hasSessionId) { String fragment = url.getRawFragment();
finalUrl += "&sessionId=" + shortSessionId; if (fragment != null) {
finalUrl.append('#').append(fragment);
} }
if (!hasSecret) { return finalUrl.toString();
finalUrl += "&secret=" + this.getOpenViduSecret();
}
}
if (url.getRef() != null) {
finalUrl += "#" + url.getRef();
}
return finalUrl;
} }
} }

View File

@ -20,8 +20,6 @@ package io.openvidu.server.core;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.RandomStringUtils;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonNull; import com.google.gson.JsonNull;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -33,6 +31,7 @@ import io.openvidu.java.client.KurentoOptions;
import io.openvidu.java.client.OpenViduRole; import io.openvidu.java.client.OpenViduRole;
import io.openvidu.server.core.Participant.ParticipantStatus; import io.openvidu.server.core.Participant.ParticipantStatus;
import io.openvidu.server.coturn.TurnCredentials; import io.openvidu.server.coturn.TurnCredentials;
import io.openvidu.server.utils.RandomIdGenerator;
public class Token { public class Token {
@ -43,7 +42,7 @@ public class Token {
private TurnCredentials turnCredentials; private TurnCredentials turnCredentials;
private String connectionId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID private String connectionId = IdentifierPrefixes.PARTICIPANT_PUBLIC_ID
+ RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(9); + RandomIdGenerator.alphabetic(1).toUpperCase() + RandomIdGenerator.alphanumeric(9);
public Token(String token, String sessionId, ConnectionProperties connectionProperties, public Token(String token, String sessionId, ConnectionProperties connectionProperties,
TurnCredentials turnCredentials) { TurnCredentials turnCredentials) {

View File

@ -17,7 +17,6 @@
package io.openvidu.server.core; package io.openvidu.server.core;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import io.openvidu.java.client.ConnectionProperties; import io.openvidu.java.client.ConnectionProperties;
@ -30,6 +29,7 @@ import io.openvidu.server.config.OpenviduBuildInfo;
import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.coturn.CoturnCredentialsService; import io.openvidu.server.coturn.CoturnCredentialsService;
import io.openvidu.server.coturn.TurnCredentials; import io.openvidu.server.coturn.TurnCredentials;
import io.openvidu.server.utils.RandomIdGenerator;
import java.util.List; import java.util.List;
@ -48,8 +48,8 @@ public class TokenGenerator {
KurentoOptions kurentoOptions, List<IceServerProperties> customIceServers) throws Exception { KurentoOptions kurentoOptions, List<IceServerProperties> customIceServers) throws Exception {
String token = OpenViduServer.wsUrl; String token = OpenViduServer.wsUrl;
token += "?sessionId=" + sessionId; token += "?sessionId=" + sessionId;
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(15); + RandomIdGenerator.alphanumeric(15);
TurnCredentials turnCredentials = coturnCredentialsService.createUser(); TurnCredentials turnCredentials = coturnCredentialsService.createUser();
ConnectionProperties.Builder connectionPropertiesBuilder = new ConnectionProperties.Builder() ConnectionProperties.Builder connectionPropertiesBuilder = new ConnectionProperties.Builder()
.type(ConnectionType.WEBRTC).data(serverMetadata).record(record).role(role) .type(ConnectionType.WEBRTC).data(serverMetadata).record(record).role(role)

View File

@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.function.Function; import java.util.function.Function;
import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.Continuation; import org.kurento.client.Continuation;
import org.kurento.client.Endpoint; import org.kurento.client.Endpoint;
import org.kurento.client.ErrorEvent; import org.kurento.client.ErrorEvent;
@ -57,6 +56,7 @@ import io.openvidu.server.kurento.endpoint.MediaEndpoint;
import io.openvidu.server.kurento.endpoint.PublisherEndpoint; import io.openvidu.server.kurento.endpoint.PublisherEndpoint;
import io.openvidu.server.kurento.endpoint.SubscriberEndpoint; import io.openvidu.server.kurento.endpoint.SubscriberEndpoint;
import io.openvidu.server.recording.service.RecordingManager; import io.openvidu.server.recording.service.RecordingManager;
import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RemoteOperationUtils; import io.openvidu.server.utils.RemoteOperationUtils;
public class KurentoParticipant extends Participant { public class KurentoParticipant extends Participant {
@ -436,7 +436,7 @@ public class KurentoParticipant extends Participant {
public String generateStreamId(MediaOptions mediaOptions) { public String generateStreamId(MediaOptions mediaOptions) {
String type = mediaOptions.hasVideo() ? mediaOptions.getTypeOfVideo() : "MICRO"; String type = mediaOptions.hasVideo() ? mediaOptions.getTypeOfVideo() : "MICRO";
return IdentifierPrefixes.STREAM_ID + type.substring(0, Math.min(type.length(), 3)) + "_" return IdentifierPrefixes.STREAM_ID + type.substring(0, Math.min(type.length(), 3)) + "_"
+ RandomStringUtils.randomAlphabetic(1).toUpperCase() + RandomStringUtils.randomAlphanumeric(3) + "_" + RandomIdGenerator.alphabetic(1).toUpperCase() + RandomIdGenerator.alphanumeric(3) + "_"
+ this.getParticipantPublicId(); + this.getParticipantPublicId();
} }

View File

@ -30,7 +30,6 @@ import java.util.concurrent.TimeUnit;
import jakarta.annotation.PreDestroy; import jakarta.annotation.PreDestroy;
import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.GenericMediaElement; import org.kurento.client.GenericMediaElement;
import org.kurento.client.GenericMediaEvent; import org.kurento.client.GenericMediaEvent;
import org.kurento.client.IceCandidate; import org.kurento.client.IceCandidate;
@ -77,6 +76,7 @@ import io.openvidu.server.kurento.kms.KmsManager;
import io.openvidu.server.rpc.RpcHandler; import io.openvidu.server.rpc.RpcHandler;
import io.openvidu.server.utils.GeoLocation; import io.openvidu.server.utils.GeoLocation;
import io.openvidu.server.utils.JsonUtils; import io.openvidu.server.utils.JsonUtils;
import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RecordingUtils; import io.openvidu.server.utils.RecordingUtils;
import io.openvidu.server.utils.SDPMunging; import io.openvidu.server.utils.SDPMunging;
@ -1169,15 +1169,15 @@ public class KurentoSessionManager extends SessionManager {
} }
String rtspConnectionId = kMediaOptions.getTypeOfVideo() + "_" + protocol + "_" String rtspConnectionId = kMediaOptions.getTypeOfVideo() + "_" + protocol + "_"
+ RandomStringUtils.randomAlphanumeric(4).toUpperCase() + "_" + uri.getHost() + RandomIdGenerator.alphanumeric(4).toUpperCase() + "_" + uri.getHost()
+ (uri.getPort() != -1 ? (":" + uri.getPort()) : "") + uri.getPath(); + (uri.getPort() != -1 ? (":" + uri.getPort()) : "") + uri.getPath();
rtspConnectionId = rtspConnectionId.replace("/", "_").replace("-", "").replace(".", "_").replace(":", "_"); rtspConnectionId = rtspConnectionId.replace("/", "_").replace("-", "").replace(".", "_").replace(":", "_");
rtspConnectionId = IdentifierPrefixes.IPCAM_ID + rtspConnectionId; rtspConnectionId = IdentifierPrefixes.IPCAM_ID + rtspConnectionId;
// Store a "fake" participant for the IpCam connection // Store a "fake" participant for the IpCam connection
this.newInsecureParticipant(rtspConnectionId); this.newInsecureParticipant(rtspConnectionId);
String token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() String token = IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(15); + RandomIdGenerator.alphanumeric(15);
this.newTokenForInsecureUser(session, token, connectionProperties, null); this.newTokenForInsecureUser(session, token, connectionProperties, null);
final Token tokenObj = session.consumeToken(token); final Token tokenObj = session.consumeToken(token);

View File

@ -17,8 +17,8 @@
package io.openvidu.server.kurento.kms; package io.openvidu.server.kurento.kms;
import java.net.MalformedURLException; import java.net.URI;
import java.net.URL; import java.net.URISyntaxException;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -82,13 +82,13 @@ public class Kms {
this.uri = props.getUri(); this.uri = props.getUri();
String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://"); String parsedUri = uri.replaceAll("^ws://", "http://").replaceAll("^wss://", "https://");
URL url = null;
try { try {
url = new URL(parsedUri); URI url = new URI(parsedUri);
} catch (MalformedURLException e) {
log.error(e.getMessage());
}
this.ip = url.getHost(); this.ip = url.getHost();
} catch (URISyntaxException e) {
log.error(e.getMessage());
this.ip = null;
}
this.loadManager = loadManager; this.loadManager = loadManager;
this.kmsManager = kmsManager; this.kmsManager = kmsManager;

View File

@ -32,7 +32,6 @@ import java.util.stream.Collectors;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.KurentoClient; import org.kurento.client.KurentoClient;
import org.kurento.commons.exception.KurentoException; import org.kurento.commons.exception.KurentoException;
import org.kurento.jsonrpc.JsonRpcClientClosedException; import org.kurento.jsonrpc.JsonRpcClientClosedException;
@ -53,6 +52,7 @@ import io.openvidu.server.core.SessionEventsHandler;
import io.openvidu.server.core.SessionManager; import io.openvidu.server.core.SessionManager;
import io.openvidu.server.kurento.core.KurentoSession; import io.openvidu.server.kurento.core.KurentoSession;
import io.openvidu.server.utils.MediaNodeManager; import io.openvidu.server.utils.MediaNodeManager;
import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RemoteOperationUtils; import io.openvidu.server.utils.RemoteOperationUtils;
import io.openvidu.server.utils.UpdatableTimerTask; import io.openvidu.server.utils.UpdatableTimerTask;
@ -408,8 +408,8 @@ public abstract class KmsManager {
} }
public static String generateKmsId() { public static String generateKmsId() {
return IdentifierPrefixes.MEDIA_NODE_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() return IdentifierPrefixes.MEDIA_NODE_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(7); + RandomIdGenerator.alphanumeric(7);
} }
public void nodeCrashedHandler(Kms kms, boolean mustRemoveMediaNode) { public void nodeCrashedHandler(Kms kms, boolean mustRemoveMediaNode) {

View File

@ -17,7 +17,6 @@
package io.openvidu.server.recording; package io.openvidu.server.recording;
import org.apache.commons.lang3.StringUtils;
import org.kurento.client.RecorderEndpoint; import org.kurento.client.RecorderEndpoint;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -61,8 +60,12 @@ public class RecorderEndpointWrapper {
public RecorderEndpointWrapper(JsonObject json, String fileExtension) { public RecorderEndpointWrapper(JsonObject json, String fileExtension) {
String nameAux = json.get("name").getAsString(); String nameAux = json.get("name").getAsString();
// If the name includes the extension, remove it // If the name includes the extension, remove it without relying on deprecated helpers
this.name = StringUtils.removeEnd(nameAux, fileExtension); if (fileExtension != null && !fileExtension.isEmpty() && nameAux.endsWith(fileExtension)) {
this.name = nameAux.substring(0, nameAux.length() - fileExtension.length());
} else {
this.name = nameAux;
}
this.fileExtension = fileExtension; this.fileExtension = fileExtension;
this.connectionId = json.get("connectionId").getAsString(); this.connectionId = json.get("connectionId").getAsString();
this.streamId = json.get("streamId").getAsString(); this.streamId = json.get("streamId").getAsString();

View File

@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -70,6 +69,7 @@ import io.openvidu.server.core.Token;
import io.openvidu.server.kurento.core.KurentoMediaOptions; import io.openvidu.server.kurento.core.KurentoMediaOptions;
import io.openvidu.server.recording.Recording; import io.openvidu.server.recording.Recording;
import io.openvidu.server.recording.service.RecordingManager; import io.openvidu.server.recording.service.RecordingManager;
import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.RestUtils; import io.openvidu.server.utils.RestUtils;
/** /**
@ -149,8 +149,8 @@ public class SessionRestController {
} }
} }
} else { } else {
sessionId = IdentifierPrefixes.SESSION_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() sessionId = IdentifierPrefixes.SESSION_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(9); + RandomIdGenerator.alphanumeric(9);
} }
Session sessionNotActive = sessionManager.storeSessionNotActive(sessionId, sessionProperties); Session sessionNotActive = sessionManager.storeSessionNotActive(sessionId, sessionProperties);
@ -652,11 +652,26 @@ public class SessionRestController {
String sessionId; String sessionId;
String type; String type;
ArrayList<String> to; List<String> to = null;
String data; String data;
try { try {
sessionId = (String) params.get("session"); sessionId = (String) params.get("session");
to = (ArrayList<String>) params.get("to"); Object toParam = params.get("to");
if (toParam instanceof List<?> rawList) {
List<String> target = new ArrayList<>(rawList.size());
for (Object element : rawList) {
if (element == null) {
target.add(null);
} else if (element instanceof String stringValue) {
target.add(stringValue);
} else {
throw new ClassCastException("Expected String elements in 'to' parameter");
}
}
to = target;
} else if (toParam != null) {
throw new ClassCastException("Expected 'to' parameter to be a list");
}
type = (String) params.get("type"); type = (String) params.get("type");
data = (String) params.get("data"); data = (String) params.get("data");
} catch (ClassCastException e) { } catch (ClassCastException e) {

View File

@ -27,7 +27,6 @@ import java.util.concurrent.ConcurrentMap;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.kurento.jsonrpc.DefaultJsonRpcHandler; import org.kurento.jsonrpc.DefaultJsonRpcHandler;
import org.kurento.jsonrpc.Session; import org.kurento.jsonrpc.Session;
@ -60,6 +59,7 @@ import io.openvidu.server.core.SessionManager;
import io.openvidu.server.core.Token; import io.openvidu.server.core.Token;
import io.openvidu.server.utils.GeoLocation; import io.openvidu.server.utils.GeoLocation;
import io.openvidu.server.utils.GeoLocationByIp; import io.openvidu.server.utils.GeoLocationByIp;
import io.openvidu.server.utils.RandomIdGenerator;
import io.openvidu.server.utils.VersionComparator; import io.openvidu.server.utils.VersionComparator;
import io.openvidu.server.utils.VersionComparator.VersionMismatchException; import io.openvidu.server.utils.VersionComparator.VersionMismatchException;
@ -283,8 +283,8 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
sessionManager.newInsecureParticipant(participantPrivateId); sessionManager.newInsecureParticipant(participantPrivateId);
token = IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() token = IdentifierPrefixes.TOKEN_ID + RandomIdGenerator.alphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(15); + RandomIdGenerator.alphanumeric(15);
ConnectionProperties connectionProperties = new ConnectionProperties.Builder().type(ConnectionType.WEBRTC) ConnectionProperties connectionProperties = new ConnectionProperties.Builder().type(ConnectionType.WEBRTC)
.role(OpenViduRole.SUBSCRIBER).build(); .role(OpenViduRole.SUBSCRIBER).build();

View File

@ -0,0 +1,36 @@
package io.openvidu.server.utils;
import java.util.concurrent.ThreadLocalRandom;
/**
* Utility methods for generating short random identifiers without relying on
* deprecated Apache Commons Lang helpers.
*/
public final class RandomIdGenerator {
private static final char[] ALPHABETIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
private static final char[] ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
private RandomIdGenerator() {
}
public static String alphabetic(int length) {
return generate(length, ALPHABETIC);
}
public static String alphanumeric(int length) {
return generate(length, ALPHANUMERIC);
}
private static String generate(int length, char[] alphabet) {
if (length < 0) {
throw new IllegalArgumentException("Length must be non-negative");
}
char[] result = new char[length];
ThreadLocalRandom random = ThreadLocalRandom.current();
for (int i = 0; i < length; i++) {
result[i] = alphabet[random.nextInt(alphabet.length)];
}
return new String(result);
}
}

View File

@ -32,13 +32,13 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import io.openvidu.server.core.SessionManager; import io.openvidu.server.core.SessionManager;
import io.openvidu.server.recording.service.RecordingManager; import io.openvidu.server.recording.service.RecordingManager;
@ -57,10 +57,10 @@ class OpenViduServerPublicRecordingsSecurityIntegrationTest {
@Autowired @Autowired
private MockMvc mockMvc; private MockMvc mockMvc;
@MockBean @MockitoBean
private SessionManager sessionManager; private SessionManager sessionManager;
@MockBean @MockitoBean
private RecordingManager recordingManager; private RecordingManager recordingManager;
@BeforeEach @BeforeEach

View File

@ -37,7 +37,6 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -47,6 +46,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import io.openvidu.server.core.SessionManager; import io.openvidu.server.core.SessionManager;
import io.openvidu.server.recording.service.RecordingManager; import io.openvidu.server.recording.service.RecordingManager;
@ -65,10 +65,10 @@ class OpenViduServerSecurityIntegrationTest {
@Autowired @Autowired
private MockMvc mockMvc; private MockMvc mockMvc;
@MockBean @MockitoBean
private SessionManager sessionManager; private SessionManager sessionManager;
@MockBean @MockitoBean
private RecordingManager recordingManager; private RecordingManager recordingManager;
@BeforeEach @BeforeEach