diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java index 0ef35a33..47598431 100644 --- a/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java @@ -489,8 +489,10 @@ public class RecordingProperties { } if (json.has("outputMode")) { outputModeAux = OutputMode.valueOf(json.get("outputMode").getAsString()); - builder.outputMode(outputModeAux); + } else { + outputModeAux = DefaultValues.outputMode; } + builder.outputMode(outputModeAux); if ((OutputMode.COMPOSED.equals(outputModeAux) || OutputMode.COMPOSED_QUICK_START.equals(outputModeAux)) && hasVideoAux) { if (json.has("recordingLayout")) { diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java index 9321925f..f38f122a 100644 --- a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java @@ -17,7 +17,11 @@ package io.openvidu.java.client; +import java.util.Map; + +import com.google.gson.Gson; import com.google.gson.JsonObject; +import com.google.gson.JsonParser; /** * See {@link io.openvidu.java.client.OpenVidu#createSession(SessionProperties)} @@ -290,4 +294,139 @@ public class SessionProperties { return json; } + /** + * Obtain a {@link SessionProperties.Builder} directly from a JSON object in the + * form of a Map + * + * @return A {@link SessionProperties.Builder} + * @throws IllegalArgumentException If some parameter has a wrong type or an + * invalid value + */ + public static SessionProperties.Builder fromJson(Map params) throws IllegalArgumentException { + + SessionProperties.Builder builder = new SessionProperties.Builder(); + String customSessionId = null; + + if (params != null) { + + // Obtain primitive values from the params map + String mediaModeString; + String recordingModeString; + String forcedVideoCodecStr; + Boolean allowTranscoding; + try { + mediaModeString = (String) params.get("mediaMode"); + recordingModeString = (String) params.get("recordingMode"); + customSessionId = (String) params.get("customSessionId"); + forcedVideoCodecStr = (String) params.get("forcedVideoCodec"); + allowTranscoding = (Boolean) params.get("allowTranscoding"); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Type error in some parameter: " + e.getMessage()); + } + + // Parse obtained values into actual types + VideoCodec forcedVideoCodec = null; + try { + forcedVideoCodec = VideoCodec.valueOf(forcedVideoCodecStr); + } catch (NullPointerException e) { + // Not an error: "forcedVideoCodec" was not provided in params. + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid value for parameter 'forcedVideoCodec': " + e.getMessage()); + } + + try { + // Safe parameter retrieval. Default values if not defined + if (recordingModeString != null) { + RecordingMode recordingMode = RecordingMode.valueOf(recordingModeString); + builder = builder.recordingMode(recordingMode); + } else { + builder = builder.recordingMode(RecordingMode.MANUAL); + } + if (mediaModeString != null) { + MediaMode mediaMode = MediaMode.valueOf(mediaModeString); + builder = builder.mediaMode(mediaMode); + } else { + builder = builder.mediaMode(MediaMode.ROUTED); + } + if (customSessionId != null && !customSessionId.isEmpty()) { + if (!isValidCustomSessionId(customSessionId)) { + throw new IllegalArgumentException( + "Parameter 'customSessionId' is wrong. Must be an alphanumeric string [a-zA-Z0-9_-]"); + } + builder = builder.customSessionId(customSessionId); + } + + if (forcedVideoCodec != null) { + builder = builder.forcedVideoCodec(forcedVideoCodec); + builder = builder.forcedVideoCodecResolved(forcedVideoCodec); + } + + if (allowTranscoding != null) { + builder = builder.allowTranscoding(allowTranscoding); + } + + JsonObject defaultRecordingPropertiesJson = null; + if (params.get("defaultRecordingProperties") != null) { + try { + defaultRecordingPropertiesJson = new Gson() + .toJsonTree(params.get("defaultRecordingProperties"), Map.class).getAsJsonObject(); + } catch (Exception e) { + throw new IllegalArgumentException( + "Error in parameter 'defaultRecordingProperties'. It is not a valid JSON object"); + } + } + if (defaultRecordingPropertiesJson != null) { + try { + RecordingProperties defaultRecordingProperties = RecordingProperties + .fromJson(defaultRecordingPropertiesJson); + builder = builder.defaultRecordingProperties(defaultRecordingProperties); + } catch (Exception e) { + throw new IllegalArgumentException( + "Parameter 'defaultRecordingProperties' is not valid: " + e.getMessage()); + } + } else { + builder.defaultRecordingProperties(new RecordingProperties.Builder().build()); + } + + String mediaNode = getMediaNodeProperty(params); + if (mediaNode != null) { + builder = builder.mediaNode(mediaNode); + } + + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Some parameter is not valid. " + e.getMessage()); + } + } + return builder; + } + + /** + * @hidden + */ + public static String getMediaNodeProperty(Map params) throws IllegalArgumentException { + if (params.containsKey("mediaNode") && params.get("mediaNode") != null) { + JsonObject mediaNodeJson; + try { + mediaNodeJson = JsonParser.parseString(params.get("mediaNode").toString()).getAsJsonObject(); + } catch (Exception e) { + throw new IllegalArgumentException("Error in parameter 'mediaNode'. It is not a valid JSON object"); + } + if (!mediaNodeJson.has("id")) { + throw new IllegalArgumentException("Error in parameter 'mediaNode'. Property 'id' not found"); + } + String mediaNode; + try { + mediaNode = mediaNodeJson.get("id").getAsString(); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Type error in parameter 'mediaNode.id': " + e.getMessage()); + } + return mediaNode; + } + return null; + } + + private static boolean isValidCustomSessionId(String customSessionId) { + return customSessionId.matches("[a-zA-Z0-9_-]+"); + } + } diff --git a/openvidu-java-client/src/test/java/io/openvidu/java/client/test/OpenViduTest.java b/openvidu-java-client/src/test/java/io/openvidu/java/client/test/OpenViduTest.java index d83352ca..f55801c3 100644 --- a/openvidu-java-client/src/test/java/io/openvidu/java/client/test/OpenViduTest.java +++ b/openvidu-java-client/src/test/java/io/openvidu/java/client/test/OpenViduTest.java @@ -7,32 +7,27 @@ 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 ); - } +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 ); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(OpenViduTest.class); + } - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } + /** + * Rigourous Test :-) + */ + public void testApp() { + assertTrue(true); + } } diff --git a/openvidu-java-client/src/test/java/io/openvidu/java/client/test/SessionPropertiesTest.java b/openvidu-java-client/src/test/java/io/openvidu/java/client/test/SessionPropertiesTest.java new file mode 100644 index 00000000..67251128 --- /dev/null +++ b/openvidu-java-client/src/test/java/io/openvidu/java/client/test/SessionPropertiesTest.java @@ -0,0 +1,55 @@ +package io.openvidu.java.client.test; + +import static org.junit.Assert.assertThrows; + +import java.util.Map; + +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 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); + Map map = mapFromJsonString(jsonString); + SessionProperties.Builder builder = SessionProperties.fromJson(map); + SessionProperties props = builder.build(); + JsonObject finalJson = props.toJson(); + assertEquals(originalJson, finalJson); + } + + public void testFromJsonError() { + Map 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"); + } + + private Map mapFromJsonString(String json) { + return new Gson().fromJson(json, Map.class); + } + + private void assertException(Map params, String containsError) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> SessionProperties.fromJson(params)); + assertTrue(exception.getMessage().contains(containsError)); + } +} diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java index 423bfb46..fba84303 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java @@ -61,7 +61,6 @@ import io.openvidu.java.client.MediaMode; import io.openvidu.java.client.OpenViduRole; import io.openvidu.java.client.Recording.OutputMode; import io.openvidu.java.client.RecordingLayout; -import io.openvidu.java.client.RecordingMode; import io.openvidu.java.client.RecordingProperties; import io.openvidu.java.client.SessionProperties; import io.openvidu.java.client.VideoCodec; @@ -106,7 +105,7 @@ public class SessionRestController { SessionProperties sessionProperties; try { - sessionProperties = getSessionPropertiesFromParams(params).build(); + sessionProperties = getSessionPropertiesFromParams((Map) params).build(); } catch (Exception e) { return this.generateErrorResponse(e.getMessage(), "/sessions", HttpStatus.BAD_REQUEST); } @@ -780,22 +779,15 @@ public class SessionRestController { } } - protected SessionProperties.Builder getSessionPropertiesFromParams(Map params) throws Exception { + protected SessionProperties.Builder getSessionPropertiesFromParams(Map params) throws Exception { - SessionProperties.Builder builder = new SessionProperties.Builder(); - String customSessionId = null; + SessionProperties.Builder builder = SessionProperties.fromJson(params); if (params != null) { - // Obtain primitive values from the params map - String mediaModeString; - String recordingModeString; String forcedVideoCodecStr; Boolean allowTranscoding; try { - mediaModeString = (String) params.get("mediaMode"); - recordingModeString = (String) params.get("recordingMode"); - customSessionId = (String) params.get("customSessionId"); forcedVideoCodecStr = (String) params.get("forcedVideoCodec"); allowTranscoding = (Boolean) params.get("allowTranscoding"); } catch (ClassCastException e) { @@ -807,32 +799,12 @@ public class SessionRestController { try { forcedVideoCodec = VideoCodec.valueOf(forcedVideoCodecStr); } catch (NullPointerException e) { - // Not an error: "forcedVideoCodec" was not provided in params. + // Not an error: "forcedVideoCodec" was not provided in params } catch (IllegalArgumentException e) { throw new Exception("Invalid value for parameter 'forcedVideoCodec': " + e.getMessage()); } try { - // Safe parameter retrieval. Default values if not defined - if (recordingModeString != null) { - RecordingMode recordingMode = RecordingMode.valueOf(recordingModeString); - builder = builder.recordingMode(recordingMode); - } else { - builder = builder.recordingMode(RecordingMode.MANUAL); - } - if (mediaModeString != null) { - MediaMode mediaMode = MediaMode.valueOf(mediaModeString); - builder = builder.mediaMode(mediaMode); - } else { - builder = builder.mediaMode(MediaMode.ROUTED); - } - if (customSessionId != null && !customSessionId.isEmpty()) { - if (!sessionManager.formatChecker.isValidCustomSessionId(customSessionId)) { - throw new Exception( - "Parameter 'customSessionId' is wrong. Must be an alphanumeric string [a-zA-Z0-9_-]"); - } - builder = builder.customSessionId(customSessionId); - } if (forcedVideoCodec == null) { forcedVideoCodec = openviduConfig.getOpenviduForcedCodec(); @@ -858,28 +830,6 @@ public class SessionRestController { builder = builder.allowTranscoding(openviduConfig.isOpenviduAllowingTranscoding()); } - JsonObject defaultRecordingPropertiesJson = null; - if (params.get("defaultRecordingProperties") != null) { - try { - defaultRecordingPropertiesJson = new Gson() - .toJsonTree(params.get("defaultRecordingProperties"), Map.class).getAsJsonObject(); - } catch (Exception e) { - throw new Exception( - "Error in parameter 'defaultRecordingProperties'. It is not a valid JSON object"); - } - } - if (defaultRecordingPropertiesJson != null) { - try { - RecordingProperties defaultRecordingProperties = RecordingProperties - .fromJson(defaultRecordingPropertiesJson); - builder = builder.defaultRecordingProperties(defaultRecordingProperties); - } catch (Exception e) { - throw new Exception("Parameter 'defaultRecordingProperties' is not valid: " + e.getMessage()); - } - } else { - builder.defaultRecordingProperties(new RecordingProperties.Builder().build()); - } - } catch (IllegalArgumentException e) { throw new Exception("Some parameter is not valid. " + e.getMessage()); }