Update Spring Boot to 2.7.5

pull/772/head
pabloFuente 2022-11-27 17:24:50 +01:00
parent 86d1260395
commit 13f404d072
16 changed files with 164 additions and 179 deletions

View File

@ -60,11 +60,17 @@
<version>${version.kurento}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${version.hamcrest}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@ -15,9 +15,11 @@
*/
package io.openvidu.client.test;
import static io.openvidu.client.internal.ProtocolElements.*;
import static io.openvidu.client.internal.ProtocolElements.JOINROOM_METHOD;
import static io.openvidu.client.internal.ProtocolElements.JOINROOM_ROOM_PARAM;
import static io.openvidu.client.internal.ProtocolElements.JOINROOM_USER_PARAM;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -26,8 +28,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.kurento.jsonrpc.client.JsonRpcClient;
import com.google.gson.JsonArray;
@ -44,31 +46,31 @@ import io.openvidu.client.ServerJsonRpcHandler;
*/
public class OpenViduClientTest {
private OpenViduClient client;
private ServerJsonRpcHandler serverHandler;
private JsonRpcClient jsonRpcClient;
private static OpenViduClient client;
private static ServerJsonRpcHandler serverHandler;
private static JsonRpcClient jsonRpcClient;
@Before
public void setup() {
jsonRpcClient = mock(JsonRpcClient.class);
serverHandler = new ServerJsonRpcHandler();
client = new OpenViduClient(jsonRpcClient, serverHandler);
}
@BeforeAll
public static void setup() {
jsonRpcClient = mock(JsonRpcClient.class);
serverHandler = new ServerJsonRpcHandler();
client = new OpenViduClient(jsonRpcClient, serverHandler);
}
@Test
public void testRoomJoin() throws IOException {
JsonObject params = new JsonObject();
params.addProperty(JOINROOM_ROOM_PARAM, "room");
params.addProperty(JOINROOM_USER_PARAM, "user");
@Test
public void testRoomJoin() throws IOException {
JsonObject params = new JsonObject();
params.addProperty(JOINROOM_ROOM_PARAM, "room");
params.addProperty(JOINROOM_USER_PARAM, "user");
JsonObject result = new JsonObject();
JsonArray value = new JsonArray();
result.add("value", value);
JsonObject result = new JsonObject();
JsonArray value = new JsonArray();
result.add("value", value);
Map<String, List<String>> joinResult = new HashMap<String, List<String>>();
Map<String, List<String>> joinResult = new HashMap<String, List<String>>();
when(jsonRpcClient.sendRequest(JOINROOM_METHOD, params)).thenReturn(result);
assertThat(client.joinRoom("room", "user"), is(joinResult));
when(jsonRpcClient.sendRequest(JOINROOM_METHOD, params)).thenReturn(result);
assertThat(client.joinRoom("room", "user"), is(joinResult));
}
}
}

View File

@ -78,12 +78,12 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -1,11 +1,15 @@
package io.openvidu.java.client;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class OpenViduHttpExceptionTest {
@Test(expected = OpenViduException.class)
public void shouldThrowGenericOpenViduException() throws OpenViduHttpException {
throw new OpenViduHttpException(401);
}
@Test
public void shouldThrowGenericOpenViduException() {
assertThrows(OpenViduException.class, () -> {
throw new OpenViduHttpException(401);
});
}
}

View File

@ -1,11 +1,15 @@
package io.openvidu.java.client;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
public class OpenViduJavaClientExceptionTest {
@Test(expected = OpenViduException.class)
public void shouldThrowGenericOpenViduException() throws OpenViduJavaClientException {
throw new OpenViduJavaClientException("message");
}
@Test
public void shouldThrowGenericOpenViduException() {
assertThrows(OpenViduException.class, () -> {
throw new OpenViduJavaClientException("message");
});
}
}

View File

@ -1,27 +1,18 @@
package io.openvidu.java.client.test;
import static org.junit.Assert.assertThrows;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.openvidu.java.client.ConnectionProperties;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class ConnectionPropertiesTest extends TestCase {
public ConnectionPropertiesTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(ConnectionPropertiesTest.class);
}
public class ConnectionPropertiesTest {
@Test
public void testWebrtcFromJsonSuccess() {
String jsonString = "{'type':'WEBRTC','data':'MY_CUSTOM_STRING','record':false,'role':'SUBSCRIBER','kurentoOptions':{'videoMaxRecvBandwidth':333,'videoMinRecvBandwidth':333,'videoMaxSendBandwidth':333,'videoMinSendBandwidth':333,'allowedFilters':['CustomFilter']},'customIceServers':[{'url':'turn:turn-domain.com:443','username':'MY_CUSTOM_STRING','credential':'MY_CUSTOM_STRING'}]}";
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
@ -30,9 +21,10 @@ public class ConnectionPropertiesTest extends TestCase {
ConnectionProperties props = builder.build();
JsonObject finalJson = props.toJson("MY_CUSTOM_STRING");
finalJson = removeIpcamProps(finalJson);
assertEquals(originalJson, finalJson);
Assertions.assertEquals(originalJson, finalJson);
}
@Test
public void testIpcamFromJsonSuccess() {
String jsonString = "{'type':'IPCAM','data':'MY_CUSTOM_STRING','record':false,'rtspUri':'rtsp://your.camera.ip.sdp','adaptativeBitrate':false,'onlyPlayWithSubscribers':false,'networkCache':333}";
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
@ -41,7 +33,7 @@ public class ConnectionPropertiesTest extends TestCase {
ConnectionProperties props = builder.build();
JsonObject finalJson = props.toJson("MY_CUSTOM_STRING");
finalJson = removeWebrtcProps(finalJson);
assertEquals(originalJson, finalJson);
Assertions.assertEquals(originalJson, finalJson);
jsonString = "{'type':'IPCAM','rtspUri':'rtsp://your.camera.ip.sdp'}";
ConnectionProperties.fromJson(mapFromJsonString(jsonString)).build();
@ -59,6 +51,7 @@ public class ConnectionPropertiesTest extends TestCase {
ConnectionProperties.fromJson(mapFromJsonString(jsonString)).build();
}
@Test
public void testFromJsonError() {
Map<String, ?> map = mapFromJsonString("{'type':'NOT_EXISTS'}");
assertException(map, "type");
@ -107,8 +100,8 @@ public class ConnectionPropertiesTest extends TestCase {
}
private void assertException(Map<String, ?> params, String containsError) {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class,
() -> ConnectionProperties.fromJson(params));
assertTrue(exception.getMessage().contains(containsError));
Assertions.assertTrue(exception.getMessage().contains(containsError));
}
}

View File

@ -3,21 +3,14 @@ package io.openvidu.java.client.test;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import io.openvidu.java.client.utils.FormatChecker;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class FormatCheckerTest extends TestCase {
public FormatCheckerTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(FormatCheckerTest.class);
}
public class FormatCheckerTest {
@Test
public void testCustomSessionIdFormat() {
List<String> invalidCustomSessionIds = Arrays.asList("", "session#", "session!", "session*", "'session",
@ -30,11 +23,12 @@ public class FormatCheckerTest extends TestCase {
"session-_", "123_session-1");
for (String id : invalidCustomSessionIds)
assertFalse(FormatChecker.isValidCustomSessionId(id));
Assertions.assertFalse(FormatChecker.isValidCustomSessionId(id));
for (String id : validCustomSessionIds)
assertTrue(FormatChecker.isValidCustomSessionId(id));
Assertions.assertTrue(FormatChecker.isValidCustomSessionId(id));
}
@Test
public void testAcceptableRecordingResolution() {
List<String> invalidResolutions = Arrays.asList("", "a", "123", "true", "AXB", "AxB", "12x", "x12", "0920x1080",
@ -43,11 +37,12 @@ public class FormatCheckerTest extends TestCase {
List<String> validResolutions = Arrays.asList("1920x1080", "1280x720", "100x1999");
for (String resolution : invalidResolutions)
assertFalse(FormatChecker.isAcceptableRecordingResolution(resolution));
Assertions.assertFalse(FormatChecker.isAcceptableRecordingResolution(resolution));
for (String resolution : validResolutions)
assertTrue(FormatChecker.isAcceptableRecordingResolution(resolution));
Assertions.assertTrue(FormatChecker.isAcceptableRecordingResolution(resolution));
}
@Test
public void testAcceptableRecordingFrameRate() {
List<Integer> invalidFrameRates = Arrays.asList(-1, 0, 121, 9999);
@ -55,9 +50,9 @@ public class FormatCheckerTest extends TestCase {
List<Integer> validFramerates = Arrays.asList(1, 2, 30, 60, 119, 120);
for (int framerate : invalidFrameRates)
assertFalse(FormatChecker.isAcceptableRecordingFrameRate(framerate));
Assertions.assertFalse(FormatChecker.isAcceptableRecordingFrameRate(framerate));
for (int framerate : validFramerates)
assertTrue(FormatChecker.isAcceptableRecordingFrameRate(framerate));
Assertions.assertTrue(FormatChecker.isAcceptableRecordingFrameRate(framerate));
}
}

View File

@ -1,33 +0,0 @@
package io.openvidu.java.client.test;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class OpenViduTest extends TestCase {
/**
* Create the test case
*
* @param testName name of the test case
*/
public OpenViduTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(OpenViduTest.class);
}
/**
* Rigourous Test :-)
*/
public void testApp() {
assertTrue(true);
}
}

View File

@ -1,26 +1,16 @@
package io.openvidu.java.client.test;
import static org.junit.Assert.assertThrows;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.openvidu.java.client.RecordingProperties;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class RecordingPropertiesTest extends TestCase {
public RecordingPropertiesTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(RecordingPropertiesTest.class);
}
public class RecordingPropertiesTest {
/**
* { "session":"ses_YnDaGYNcd7", "name": "MyRecording", "hasAudio": true,
@ -30,6 +20,7 @@ public class RecordingPropertiesTest extends TestCase {
* "media_i-0c58bcdd26l11d0sd" } }
*/
@Test
public void testRecordingFromJsonSuccess() {
String jsonString = "{'session':'MY_CUSTOM_STRING','name':'MY_CUSTOM_STRING','hasAudio':false,'hasVideo':true,'outputMode':'COMPOSED','recordingLayout':'CUSTOM','customLayout':'MY_CUSTOM_STRING','resolution':'1000x1000','frameRate':33,'shmSize':333333333,'mediaNode':{'id':'MY_CUSTOM_STRING'}}";
Map<String, ?> map = mapFromJsonString(jsonString);
@ -40,7 +31,7 @@ public class RecordingPropertiesTest extends TestCase {
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
originalJson = adaptProps(originalJson);
assertEquals(originalJson, finalJson);
Assertions.assertEquals(originalJson, finalJson);
jsonString = "{'session':'MY_CUSTOM_STRING','name':'MY_CUSTOM_STRING','hasAudio':false,'hasVideo':true,'outputMode':'INDIVIDUAL','ignoreFailedStreams':true}";
map = mapFromJsonString(jsonString);
@ -51,9 +42,10 @@ public class RecordingPropertiesTest extends TestCase {
originalJson = new Gson().fromJson(jsonString, JsonObject.class);
originalJson = adaptProps(originalJson);
assertEquals(originalJson, finalJson);
Assertions.assertEquals(originalJson, finalJson);
}
@Test
public void testFromJsonError() {
Map<String, ?> map = mapFromJsonString("{'session':false}");
assertException(map, "Type error in some parameter", IllegalArgumentException.class);
@ -138,12 +130,12 @@ public class RecordingPropertiesTest extends TestCase {
private <T extends Exception> void assertException(Map<String, ?> params, String containsError,
Class<T> exceptionClass) {
if (exceptionClass != null) {
T exception = assertThrows(exceptionClass, () -> RecordingProperties.fromJson(params, null));
assertTrue(exception.getMessage().contains(containsError));
T exception = Assertions.assertThrows(exceptionClass, () -> RecordingProperties.fromJson(params, null));
Assertions.assertTrue(exception.getMessage().contains(containsError));
} else {
Exception exception = assertThrows(RuntimeException.class,
Exception exception = Assertions.assertThrows(RuntimeException.class,
() -> RecordingProperties.fromJson(params, null));
assertTrue(exception.getMessage().contains(containsError));
Assertions.assertTrue(exception.getMessage().contains(containsError));
}
}

View File

@ -1,27 +1,21 @@
package io.openvidu.java.client.test;
import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.openvidu.java.client.SessionProperties;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class SessionPropertiesTest extends TestCase {
public SessionPropertiesTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(SessionPropertiesTest.class);
}
public class SessionPropertiesTest {
@Test
public void testFromJsonSuccess() {
String jsonString = "{'customSessionId':'MY_CUSTOM_STRING','mediaMode':'ROUTED','recordingMode':'ALWAYS','defaultRecordingProperties':{'name':'MY_CUSTOM_STRING','hasAudio':false,'hasVideo':true,'outputMode':'COMPOSED_QUICK_START','recordingLayout':'BEST_FIT','resolution':'1920x1000','frameRate':25,'shmSize':536870911},'forcedVideoCodec':'VP8','allowTranscoding':true,'mediaNode':{'id':'MY_CUSTOM_STRING'}}";
JsonObject originalJson = new Gson().fromJson(jsonString, JsonObject.class);
@ -29,16 +23,17 @@ public class SessionPropertiesTest extends TestCase {
SessionProperties.Builder builder = SessionProperties.fromJson(map);
SessionProperties props = builder.build();
JsonObject finalJson = props.toJson();
assertEquals(originalJson, finalJson);
Assertions.assertEquals(originalJson, finalJson);
}
@Test
public void testFromJsonError() {
Map<String, ?> map = mapFromJsonString("{'mediaNode':'MY_CUSTOM_STRING'}");
assertException(map, "Error in parameter 'mediaNode'");
map = mapFromJsonString("{'customSessionId':'WRONG_CUSTOM_SESSION_ID?'}");
assertException(map, "Parameter 'customSessionId' is wrong");
// map = mapFromJsonString("{'defaultRecordingProperties':{'resolution':'2000x1000'}}");
// assertException(map, "Parameter 'customSessionId' is wrong");
}

View File

@ -316,13 +316,7 @@
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${version.hamcrest}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<artifactId>hamcrest</artifactId>
<version>${version.hamcrest}</version>
<scope>test</scope>
</dependency>

View File

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import org.bouncycastle.util.Arrays;
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
import org.kurento.jsonrpc.server.JsonRpcConfigurer;
import org.kurento.jsonrpc.server.JsonRpcHandlerRegistry;
@ -289,7 +288,13 @@ public class OpenViduServer implements JsonRpcConfigurer {
log.info("Using /dev/urandom for secure random generation");
System.setProperty("java.security.egd", "file:/dev/./urandom");
SpringApplication.run(OpenViduServer.class, Arrays.append(args, "--spring.main.banner-mode=off"));
String[] argsAux = new String[args.length + 2];
System.arraycopy(args, 0, argsAux, 0, args.length);
argsAux[argsAux.length - 2] = "--spring.main.banner-mode=off";
argsAux[argsAux.length - 1] = "--spring.main.allow-circular-references=true";
SpringApplication.run(OpenViduServer.class, argsAux);
}

View File

@ -26,8 +26,6 @@ import javax.annotation.PostConstruct;
import org.kurento.client.KurentoClient;
import org.kurento.commons.exception.KurentoException;
import org.kurento.jsonrpc.client.JsonRpcClientNettyWebSocket;
import org.kurento.jsonrpc.client.JsonRpcWSConnectionListener;
import io.openvidu.java.client.RecordingProperties;
import io.openvidu.server.core.Session;
@ -46,13 +44,8 @@ public class FixedOneKmsManager extends KmsManager {
KurentoClient kClient = null;
Kms kms = new Kms(firstProps, loadManager, this);
try {
JsonRpcWSConnectionListener listener = this.generateKurentoConnectionListener(kms.getId());
JsonRpcClientNettyWebSocket client = new JsonRpcClientNettyWebSocket(firstProps.getUri(), listener);
client.setTryReconnectingMaxTime(0);
client.setTryReconnectingForever(false);
client.setConnectionTimeout(MAX_CONNECT_TIME_MILLIS);
client.setRequestTimeout(MAX_REQUEST_TIMEOUT);
kClient = KurentoClient.createFromJsonRpcClientHonoringClientTimeouts(client);
kClient = this.createKurentoClient(kms.getId(), firstProps.getUri());
kms.setKurentoClient(kClient);
// TODO: This should be done in KurentoClient connected event

View File

@ -33,6 +33,9 @@ import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.RandomStringUtils;
import org.kurento.client.KurentoClient;
import org.kurento.jsonrpc.JsonRpcClientClosedException;
import org.kurento.jsonrpc.client.JsonRpcClientNettyWebSocket;
import org.kurento.jsonrpc.client.JsonRpcWSConnectionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -178,7 +181,18 @@ public abstract class KmsManager {
return this.mediaNodeManager;
}
protected KurentoClient createKurentoClient(String kmsId, String uri) {
JsonRpcWSConnectionListener listener = this.generateKurentoConnectionListener(kmsId);
JsonRpcClientNettyWebSocket client = new JsonRpcClientNettyWebSocket(uri, listener);
client.setTryReconnectingMaxTime(0);
client.setTryReconnectingForever(false);
client.setConnectionTimeout(MAX_CONNECT_TIME_MILLIS);
client.setRequestTimeout(MAX_REQUEST_TIMEOUT);
return KurentoClient.createFromJsonRpcClientHonoringClientTimeouts(client);
}
protected JsonRpcWSConnectionListener generateKurentoConnectionListener(final String kmsId) {
return new JsonRpcWSConnectionListener() {
@Override
@ -295,17 +309,12 @@ public abstract class KmsManager {
return;
}
try {
kms.getKurentoClient().getServerManager().getInfo();
} catch (Exception e) {
log.error(
"According to Timer KMS with uri {} and KurentoClient [{}] is not reconnected yet. Exception {}",
kms.getUri(), kms.getKurentoClient().toString(), e.getClass().getName());
if (reconnectKurentoClient(kms)) {
nodeRecoveredHandler(kms);
} else {
return;
}
nodeRecoveredHandler(kms);
}
}, () -> Long.valueOf(INTERVAL_WAIT_MS)); // Try 2 times per second
@ -316,6 +325,32 @@ public abstract class KmsManager {
};
}
private boolean reconnectKurentoClient(Kms kms) {
try {
kms.getKurentoClient().getServerManager().getInfo();
return true;
} catch (JsonRpcClientClosedException e) {
log.error(
"According to Timer KurentoClient [{}] of KMS with uri {} is closed ({}). Initializing a new KurentoClient",
kms.getKurentoClient().toString(), kms.getUri(), e.getClass().getName());
KurentoClient kClient = createKurentoClient(kms.getId(), kms.getUri());
try {
kClient.getServerManager().getInfo();
kms.setKurentoClient(kClient);
log.info("Success reconnecting to KMS with uri {} with a new KurentoClient", kms.getUri());
return true;
} catch (Exception e2) {
log.error("Error reconnecting to KMS with uri {} with a new KurentoClient. Exception {}: {}",
kms.getUri(), e2.getClass().getName(), e2.getMessage());
return false;
}
} catch (Exception e) {
log.error("According to Timer KMS with uri {} and KurentoClient [{}] is not reconnected yet. Exception {}",
kms.getUri(), kms.getKurentoClient().toString(), e.getClass().getName());
return false;
}
}
private boolean isNewKms(Kms kms) {
try {
KurentoSession kSession = kms.getKurentoSessions().iterator().next();

View File

@ -67,7 +67,8 @@ public class UpdatableTimerTask extends TimerTask {
try {
task.run();
} catch (Exception e) {
log.error("Exception running UpdatableTimerTask: {} - {}", e.getMessage(), e.getStackTrace());
log.error("Exception running UpdatableTimerTask ({}): {} - {}", e.getClass().getName(), e.getMessage(),
e.getStackTrace());
}
updateTimer();
}

13
pom.xml
View File

@ -42,20 +42,19 @@
</developers>
<properties>
<version.kurento>6.18.0</version.kurento>
<version.spring-boot>2.3.12.RELEASE</version.spring-boot>
<version.junit>4.13.2</version.junit>
<version.junit.jupiter>5.8.1</version.junit.jupiter>
<version.junit.platform>1.8.1</version.junit.platform>
<version.kurento>6.18.1-SNAPSHOT</version.kurento>
<version.spring-boot>2.7.5</version.spring-boot>
<version.junit>5.9.1</version.junit>
<version.junit.platform>1.9.1</version.junit.platform>
<version.selenium>3.141.59</version.selenium>
<version.mockito.core>3.6.0</version.mockito.core>
<version.mockito.core>4.9.0</version.mockito.core>
<version.powermock>2.0.9</version.powermock>
<version.hamcrest>2.2</version.hamcrest>
<version.httpclient>4.5.13</version.httpclient>
<version.janino>3.1.9</version.janino>
<version.commonslang>3.12.0</version.commonslang>
<version.dockerjava>3.2.13</version.dockerjava>
<version.slf4j>1.7.32</version.slf4j>
<version.slf4j>1.7.36</version.slf4j>
<version.gson>2.10</version.gson>
<version.unirest>1.4.9</version.unirest>
<version.jcodec>0.2.5</version.jcodec>