openvidu-call: Added java backend
This commit is contained in:
parent
e5a8559ac9
commit
049421e08b
24
openvidu-call/openvidu-call-back-java/.gitignore
vendored
Normal file
24
openvidu-call/openvidu-call-back-java/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
target/
|
||||
25
openvidu-call/openvidu-call-back-java/README.md
Normal file
25
openvidu-call/openvidu-call-back-java/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# openvidu-basic-java
|
||||
|
||||
This is a minimal OpenVidu server application sample built for Java with Spring Boot. Visit [Application server](https://docs.openvidu.io/en/stable/application-server/) documentation for further context.
|
||||
|
||||
It internally uses [openvidu-java-client SDK](https://docs.openvidu.io/en/stable/reference-docs/openvidu-java-client/).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Java (>=11)](https://www.java.com/en/download/manual.jsp)
|
||||
- [Maven](https://maven.apache.org)
|
||||
|
||||
## Run
|
||||
|
||||
Download repository
|
||||
|
||||
```
|
||||
git clone git@github.com:OpenVidu/openvidu-tutorials.git
|
||||
cd openvidu-tutorials/openvidu-basic-java
|
||||
```
|
||||
|
||||
Run the application
|
||||
|
||||
```
|
||||
mvn spring-boot:run
|
||||
```
|
||||
56
openvidu-call/openvidu-call-back-java/pom.xml
Normal file
56
openvidu-call/openvidu-call-back-java/pom.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-call-back-java</artifactId>
|
||||
<version>2.22.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>openvidu-call-back-java</name>
|
||||
<url>https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-call/openvidu-call-back-java</url>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>11</java.version>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<start-class>io.openvidu.basic.java.App</start-class>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>2.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,13 @@
|
||||
package io.openvidu.call.java;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(App.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package io.openvidu.call.java.controllers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.openvidu.call.java.services.OpenViduService;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.Recording;
|
||||
|
||||
@CrossOrigin(origins = "*")
|
||||
@RestController
|
||||
@RequestMapping("admin")
|
||||
public class AdminController {
|
||||
|
||||
@Value("${ADMIN_SECRET}")
|
||||
private String ADMIN_SECRET;
|
||||
|
||||
@Autowired
|
||||
private OpenViduService openviduService;
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<Map<String, Object>> login(@RequestBody(required = false) Map<String, String> params,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken, HttpServletResponse res) {
|
||||
|
||||
Map<String, Object> response = new HashMap<String, Object>();
|
||||
|
||||
String password = params.get("password");
|
||||
String sessionToken = this.openviduService.getSessionIdFromCookie(recordingToken);
|
||||
boolean isAdminTokenValid = this.openviduService.adminTokens.contains(sessionToken);
|
||||
|
||||
boolean isAuthValid = password.equals(ADMIN_SECRET) || isAdminTokenValid;
|
||||
if (isAuthValid) {
|
||||
try {
|
||||
if (sessionToken.isEmpty() || !openviduService.adminTokens.contains(sessionToken)) {
|
||||
// Save session token
|
||||
String token = UUID.randomUUID().toString();
|
||||
|
||||
Cookie cookie = new Cookie(OpenViduService.ADMIN_TOKEN_NAME, token);
|
||||
cookie.setPath("/");
|
||||
res.addCookie(cookie);
|
||||
|
||||
cookie = new Cookie("session", token);
|
||||
cookie.setPath("/");
|
||||
res.addCookie(cookie);
|
||||
|
||||
openviduService.adminTokens.add(token);
|
||||
}
|
||||
List<Recording> recordings = openviduService.listAllRecordings();
|
||||
System.out.println("Login succeeded");
|
||||
System.out.println(recordings.size() + " Recordings found");
|
||||
response.put("recordings", recordings);
|
||||
|
||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException error) {
|
||||
|
||||
error.printStackTrace();
|
||||
System.err.println(error.getMessage() + "Unexpected error getting recordings");
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Permissions denied");
|
||||
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
public ResponseEntity<Void> logout(@RequestBody(required = false) Map<String, String> params,
|
||||
@CookieValue(name = "session", defaultValue = "") String sessionToken,
|
||||
HttpServletResponse res) {
|
||||
this.openviduService.adminTokens.remove(sessionToken);
|
||||
Cookie cookie = new Cookie("session", null);
|
||||
res.addCookie(cookie);
|
||||
return new ResponseEntity<>(null, HttpStatus.OK);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,227 @@
|
||||
package io.openvidu.call.java.controllers;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.openvidu.call.java.services.OpenViduService;
|
||||
import io.openvidu.call.java.services.ProxyService;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.Recording;
|
||||
|
||||
@CrossOrigin(origins = "*")
|
||||
@RestController
|
||||
@RequestMapping("/recordings")
|
||||
public class RecordingController {
|
||||
|
||||
@Value("${RECORDING}")
|
||||
private String RECORDING;
|
||||
|
||||
@Autowired
|
||||
private OpenViduService openviduService;
|
||||
|
||||
@Autowired
|
||||
private ProxyService proxyService;
|
||||
|
||||
@GetMapping("")
|
||||
public ResponseEntity<List<Recording>> getRecordings(
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken) {
|
||||
try {
|
||||
List<Recording> recordings = new ArrayList<Recording>();
|
||||
boolean IS_RECORDING_ENABLED = RECORDING.toUpperCase().equals("ENABLED");
|
||||
String sessionId = openviduService.getSessionIdFromCookie(recordingToken);
|
||||
boolean isAdminDashboard = openviduService.adminTokens.contains(sessionId);
|
||||
|
||||
if ((!sessionId.isEmpty() && IS_RECORDING_ENABLED
|
||||
&& openviduService.isValidToken(sessionId, recordingToken)) || isAdminDashboard) {
|
||||
if (isAdminDashboard) {
|
||||
recordings = this.openviduService.listAllRecordings();
|
||||
} else {
|
||||
long date = openviduService.getDateFromCookie(recordingToken);
|
||||
recordings = openviduService.listRecordingsBySessionIdAndDate(sessionId, date);
|
||||
}
|
||||
return new ResponseEntity<>(recordings, HttpStatus.OK);
|
||||
} else {
|
||||
String message = IS_RECORDING_ENABLED ? "Permissions denied to drive recording"
|
||||
: "Recording is disabled";
|
||||
System.err.println(message);
|
||||
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
|
||||
|
||||
}
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException error) {
|
||||
error.printStackTrace();
|
||||
int code = Integer.parseInt(error.getMessage());
|
||||
String message = "Unexpected error getting all recordings";
|
||||
if (code == 404) {
|
||||
message = "No recording exist for the session";
|
||||
}
|
||||
System.err.println(message);
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/start")
|
||||
public ResponseEntity<Recording> startRecording(@RequestBody(required = false) Map<String, String> params,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken) {
|
||||
|
||||
try {
|
||||
String sessionId = params.get("sessionId");
|
||||
if (openviduService.isValidToken(sessionId, recordingToken)) {
|
||||
Recording startingRecording = openviduService.startRecording(sessionId);
|
||||
openviduService.recordingMap.get(sessionId).setRecordingId(startingRecording.getId());
|
||||
System.out.println("Starting recording in " + sessionId);
|
||||
return new ResponseEntity<>(startingRecording, HttpStatus.OK);
|
||||
|
||||
} else {
|
||||
|
||||
System.out.println("Permissions denied for starting recording in session " + sessionId);
|
||||
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException error) {
|
||||
error.printStackTrace();
|
||||
int code = Integer.parseInt(error.getMessage());
|
||||
String message = "Unexpected error starting recording";
|
||||
if (code == 409) {
|
||||
message = "The session is already being recorded.";
|
||||
} else if (code == 501) {
|
||||
message = "OpenVidu Server recording module is disabled";
|
||||
} else if (code == 406) {
|
||||
message = "The session has no connected participants";
|
||||
}
|
||||
System.err.println(message);
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/stop")
|
||||
public ResponseEntity<List<Recording>> stopRecording(@RequestBody(required = false) Map<String, String> params,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken) {
|
||||
try {
|
||||
String sessionId = params.get("sessionId");
|
||||
if (openviduService.isValidToken(sessionId, recordingToken)) {
|
||||
String recordingId = openviduService.recordingMap.get(sessionId).getRecordingId();
|
||||
|
||||
if (!recordingId.isEmpty()) {
|
||||
System.out.println("Stopping recording in " + sessionId);
|
||||
openviduService.stopRecording(recordingId);
|
||||
long date = openviduService.getDateFromCookie(recordingToken);
|
||||
List<Recording> recordingList = openviduService.listRecordingsBySessionIdAndDate(sessionId, date);
|
||||
openviduService.recordingMap.get(sessionId).setRecordingId("");
|
||||
return new ResponseEntity<>(recordingList, HttpStatus.OK);
|
||||
} else {
|
||||
System.err.println("Session was not being recorded");
|
||||
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Permissions denied to drive recording");
|
||||
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException error) {
|
||||
error.printStackTrace();
|
||||
int code = Integer.parseInt(error.getMessage());
|
||||
String message = "Unexpected error stopping recording";
|
||||
if (code == 501) {
|
||||
message = "OpenVidu Server recording module is disabled";
|
||||
} else if (code == 406) {
|
||||
message = "Recording has STARTING status. Wait until STARTED status before stopping the recording";
|
||||
}
|
||||
System.err.println(message);
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete/{recordingId}")
|
||||
public ResponseEntity<List<Recording>> deleteRecording(@PathVariable String recordingId,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken,
|
||||
@CookieValue(name = "session", defaultValue = "") String sessionToken) {
|
||||
try {
|
||||
List<Recording> recordings = new ArrayList<Recording>();
|
||||
String sessionId = openviduService.getSessionIdFromCookie(recordingToken);
|
||||
boolean isAdminDashboard = openviduService.adminTokens.contains(sessionToken);
|
||||
|
||||
if ((!sessionId.isEmpty() && openviduService.isValidToken(sessionId, recordingToken)) || isAdminDashboard) {
|
||||
if (recordingId.isEmpty()) {
|
||||
System.err.println("Missing recording id parameter.");
|
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
System.out.println("Deleting recording " + recordingId);
|
||||
openviduService.deleteRecording(recordingId);
|
||||
if (isAdminDashboard && !sessionToken.isEmpty()) {
|
||||
recordings = openviduService.listAllRecordings();
|
||||
} else {
|
||||
long date = openviduService.getDateFromCookie(recordingToken);
|
||||
recordings = openviduService.listRecordingsBySessionIdAndDate(sessionId, date);
|
||||
}
|
||||
return new ResponseEntity<>(recordings, HttpStatus.OK);
|
||||
|
||||
} else {
|
||||
System.err.println("Permissions denied to drive recording");
|
||||
return new ResponseEntity<>(recordings, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException error) {
|
||||
error.printStackTrace();
|
||||
int code = Integer.parseInt(error.getMessage());
|
||||
String message = "Unexpected error deleting the recording";
|
||||
if (code == 409) {
|
||||
message = "The recording has STARTED status. Stop it before deletion.";
|
||||
} else if (code == 501) {
|
||||
message = "OpenVidu Server recording module is disabled";
|
||||
} else if (code == 409) {
|
||||
message = "No recording exists for the session";
|
||||
}
|
||||
System.err.println(message);
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/{recordingId}/{extension}")
|
||||
public ResponseEntity<?> getRecording(@PathVariable String recordingId, @PathVariable String extension,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingToken,
|
||||
@CookieValue(name = "session", defaultValue = "") String sessionToken, HttpServletRequest req, HttpServletResponse res) {
|
||||
|
||||
boolean isAdminDashboard = openviduService.adminTokens.contains(sessionToken);
|
||||
String sessionId = this.openviduService.getSessionIdFromCookie(recordingToken);
|
||||
if ((!sessionId.isEmpty() && openviduService.isValidToken(sessionId, recordingToken)) || isAdminDashboard) {
|
||||
if (recordingId.isEmpty()) {
|
||||
System.err.println("Missing recording id parameter.");
|
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
} else {
|
||||
try {
|
||||
return proxyService.processProxyRequest(req, res);
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Permissions denied to drive recording");
|
||||
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
package io.openvidu.call.java.controllers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.openvidu.call.java.models.RecordingData;
|
||||
import io.openvidu.call.java.services.OpenViduService;
|
||||
import io.openvidu.java.client.Connection;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.OpenViduRole;
|
||||
import io.openvidu.java.client.Recording;
|
||||
import io.openvidu.java.client.Session;
|
||||
|
||||
@CrossOrigin(origins = "*")
|
||||
@RestController
|
||||
public class SessionController {
|
||||
|
||||
|
||||
@Value("${RECORDING}")
|
||||
private String RECORDING;
|
||||
|
||||
|
||||
@Autowired
|
||||
private OpenViduService openviduService;
|
||||
|
||||
|
||||
@PostMapping("/sessions")
|
||||
public ResponseEntity<Map<String, Object>> createConnection(@RequestBody(required = false) Map<String, Object> params,
|
||||
@CookieValue(name = OpenViduService.RECORDING_TOKEN_NAME, defaultValue = "") String recordingTokenCookie,
|
||||
HttpServletResponse res) {
|
||||
|
||||
Map<String, Object> response = new HashMap<String, Object>();
|
||||
try {
|
||||
long date = -1;
|
||||
String nickname = "";
|
||||
|
||||
String sessionId = params.get("sessionId").toString();
|
||||
if(params.containsKey("nickname")) {
|
||||
nickname = params.get("nickname").toString();
|
||||
}
|
||||
|
||||
Session sessionCreated = this.openviduService.createSession(sessionId);
|
||||
boolean IS_RECORDING_ENABLED = RECORDING.toUpperCase().equals("ENABLED");
|
||||
|
||||
boolean hasValidToken = this.openviduService.isValidToken(sessionId, recordingTokenCookie);
|
||||
boolean isSessionCreator = hasValidToken || sessionCreated.getActiveConnections().size() == 0;
|
||||
|
||||
OpenViduRole role = isSessionCreator && IS_RECORDING_ENABLED ? OpenViduRole.MODERATOR : OpenViduRole.PUBLISHER;
|
||||
|
||||
response.put("recordingEnabled", IS_RECORDING_ENABLED);
|
||||
response.put("recordings", new ArrayList<Recording>());
|
||||
|
||||
|
||||
Connection cameraConnection = this.openviduService.createConnection(sessionCreated, nickname, role);
|
||||
Connection screenConnection = this.openviduService.createConnection(sessionCreated, nickname, role);
|
||||
|
||||
response.put("cameraToken", cameraConnection.getToken());
|
||||
response.put("screenToken", screenConnection.getToken());
|
||||
|
||||
if (IS_RECORDING_ENABLED && isSessionCreator && !hasValidToken) {
|
||||
/**
|
||||
* ! *********** WARN *********** !
|
||||
*
|
||||
* To identify who is able to manage session recording, the code sends a cookie with a token to the session creator.
|
||||
* The relation between cookies and sessions are stored in backend memory.
|
||||
*
|
||||
* This authentication & authorization system is pretty basic and it is not for production.
|
||||
* We highly recommend IMPLEMENT YOUR OWN USER MANAGEMENT with persistence for a properly and secure recording feature.
|
||||
*
|
||||
* ! *********** WARN *********** !
|
||||
**/
|
||||
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
date = System.currentTimeMillis();
|
||||
String recordingToken = cameraConnection.getToken() + "&" + OpenViduService.RECORDING_TOKEN_NAME + "=" + uuid + "&createdAt=" +date;
|
||||
|
||||
Cookie cookie = new Cookie(OpenViduService.RECORDING_TOKEN_NAME, recordingToken);
|
||||
res.addCookie(cookie);
|
||||
|
||||
RecordingData recData = new RecordingData(recordingToken, "");
|
||||
this.openviduService.recordingMap.put(sessionId, recData);
|
||||
}
|
||||
|
||||
if(IS_RECORDING_ENABLED){
|
||||
if(date == -1) {
|
||||
date = openviduService.getDateFromCookie(recordingTokenCookie);
|
||||
}
|
||||
List<Recording> recordings = openviduService.listRecordingsBySessionIdAndDate(sessionId, date);
|
||||
response.put("recordings", recordings);
|
||||
}
|
||||
|
||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||
|
||||
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
|
||||
if(Integer.parseInt(e.getMessage()) == 501) {
|
||||
System.err.println("OpenVidu Server recording module is disabled");
|
||||
response.put("recordingEnabled", false);
|
||||
return new ResponseEntity<>(response, HttpStatus.OK);
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package io.openvidu.call.java.models;
|
||||
|
||||
public class RecordingData {
|
||||
|
||||
String token;
|
||||
String recordingId;
|
||||
public RecordingData(String token, String recordingId) {
|
||||
super();
|
||||
this.token = token;
|
||||
this.recordingId = recordingId;
|
||||
}
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
public String getRecordingId() {
|
||||
return recordingId;
|
||||
}
|
||||
public void setRecordingId(String recordingId) {
|
||||
this.recordingId = recordingId;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,171 @@
|
||||
package io.openvidu.call.java.services;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import io.openvidu.call.java.models.RecordingData;
|
||||
import io.openvidu.java.client.Connection;
|
||||
import io.openvidu.java.client.ConnectionProperties;
|
||||
import io.openvidu.java.client.OpenVidu;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.OpenViduRole;
|
||||
import io.openvidu.java.client.Recording;
|
||||
import io.openvidu.java.client.Session;
|
||||
import io.openvidu.java.client.SessionProperties;
|
||||
|
||||
@Service
|
||||
public class OpenViduService {
|
||||
|
||||
public static final String RECORDING_TOKEN_NAME = "ovCallRecordingToken";
|
||||
public static final String ADMIN_TOKEN_NAME = "ovCallAdminToken";
|
||||
public Map<String, RecordingData> recordingMap = new HashMap<String, RecordingData>();
|
||||
public List<String> adminTokens = new ArrayList<String>();
|
||||
|
||||
@Value("${OPENVIDU_URL}")
|
||||
public String OPENVIDU_URL;
|
||||
|
||||
@Value("${OPENVIDU_SECRET}")
|
||||
private String OPENVIDU_SECRET;
|
||||
|
||||
private OpenVidu openvidu;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.openvidu = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
}
|
||||
|
||||
public String getBasicAuth() {
|
||||
String stringToEncode = "OPENVIDUAPP:" + OPENVIDU_SECRET;
|
||||
byte[] encodedString = Base64.encodeBase64(stringToEncode.getBytes());
|
||||
return "Basic " + new String(encodedString);
|
||||
}
|
||||
|
||||
public long getDateFromCookie(String recordingToken) {
|
||||
|
||||
if (!recordingToken.isEmpty()) {
|
||||
MultiValueMap<String, String> cookieTokenParams = UriComponentsBuilder.fromUriString(recordingToken).build()
|
||||
.getQueryParams();
|
||||
String date = cookieTokenParams.get("createdAt").get(0);
|
||||
return Long.parseLong(date);
|
||||
} else {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public String getSessionIdFromCookie(String cookie) {
|
||||
try {
|
||||
|
||||
if (!cookie.isEmpty()) {
|
||||
MultiValueMap<String, String> cookieTokenParams = UriComponentsBuilder.fromUriString(cookie)
|
||||
.build().getQueryParams();
|
||||
return cookieTokenParams.get("sessionId").get(0);
|
||||
}
|
||||
|
||||
} catch (Exception error) {
|
||||
System.out.println("Recording cookie not found");
|
||||
System.err.println(error);
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
public boolean isValidToken(String sessionId, String recordingToken) {
|
||||
try {
|
||||
|
||||
if (!recordingToken.isEmpty()) {
|
||||
MultiValueMap<String, String> storedTokenParams = null;
|
||||
|
||||
if(this.recordingMap.containsKey(sessionId)) {
|
||||
storedTokenParams = UriComponentsBuilder
|
||||
.fromUriString(this.recordingMap.get(sessionId).getToken()).build().getQueryParams();
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> cookieTokenParams = UriComponentsBuilder
|
||||
.fromUriString(recordingToken).build().getQueryParams();
|
||||
|
||||
if (!cookieTokenParams.isEmpty() && storedTokenParams != null) {
|
||||
String cookieSessionId = cookieTokenParams.get("sessionId").get(0);
|
||||
String cookieToken = cookieTokenParams.get(RECORDING_TOKEN_NAME).get(0);
|
||||
String cookieDate = cookieTokenParams.get("createdAt").get(0);
|
||||
|
||||
String storedToken = storedTokenParams.get(RECORDING_TOKEN_NAME).get(0);
|
||||
String storedDate = storedTokenParams.get("createdAt").get(0);
|
||||
|
||||
return sessionId.equals(cookieSessionId) && cookieToken.equals(storedToken) && cookieDate.equals(storedDate);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Session createSession(String sessionId) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("customSessionId", sessionId);
|
||||
SessionProperties properties = SessionProperties.fromJson(params).build();
|
||||
Session session = openvidu.createSession(properties);
|
||||
session.fetch();
|
||||
return session;
|
||||
}
|
||||
|
||||
public Connection createConnection(Session session, String nickname, OpenViduRole role)
|
||||
throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
Map<String, Object> connectionData = new HashMap<String, Object>();
|
||||
|
||||
if (!nickname.isEmpty()) {
|
||||
connectionData.put("openviduCustomConnectionId", nickname);
|
||||
}
|
||||
params.put("role", role.name());
|
||||
params.put("data", connectionData.toString());
|
||||
ConnectionProperties properties = ConnectionProperties.fromJson(params).build();
|
||||
return session.createConnection(properties);
|
||||
|
||||
}
|
||||
|
||||
public Recording startRecording(String sessionId) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
return this.openvidu.startRecording(sessionId);
|
||||
}
|
||||
|
||||
public Recording stopRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
return this.openvidu.stopRecording(recordingId);
|
||||
}
|
||||
|
||||
public void deleteRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
this.openvidu.deleteRecording(recordingId);
|
||||
}
|
||||
|
||||
public Recording getRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
return this.openvidu.getRecording(recordingId);
|
||||
}
|
||||
|
||||
public List<Recording> listAllRecordings() throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
return this.openvidu.listRecordings();
|
||||
}
|
||||
|
||||
public List<Recording> listRecordingsBySessionIdAndDate(String sessionId, long date)
|
||||
throws OpenViduJavaClientException, OpenViduHttpException {
|
||||
List<Recording> recordings = this.listAllRecordings();
|
||||
List<Recording> recordingsAux = new ArrayList<Recording>();
|
||||
for (Recording recording : recordings) {
|
||||
if (recording.getSessionId().equals(sessionId) && date <= recording.getCreatedAt()) {
|
||||
recordingsAux.add(recording);
|
||||
}
|
||||
}
|
||||
return recordingsAux;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package io.openvidu.call.java.services;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Service
|
||||
public class ProxyService {
|
||||
|
||||
@Value("${OPENVIDU_URL}")
|
||||
public String OPENVIDU_URL;
|
||||
|
||||
@Autowired
|
||||
private OpenViduService openviduService;
|
||||
|
||||
public ResponseEntity<?> processProxyRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
throws URISyntaxException {
|
||||
|
||||
String requestUrl = request.getRequestURI();
|
||||
|
||||
URI uri = UriComponentsBuilder.fromUriString(OPENVIDU_URL).path(requestUrl).query(request.getQueryString()).build(true).toUri();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
headers.set(headerName, request.getHeader(headerName));
|
||||
}
|
||||
|
||||
headers.add("Authorization", this.openviduService.getBasicAuth());
|
||||
|
||||
headers.remove(HttpHeaders.ACCEPT_ENCODING);
|
||||
|
||||
HttpEntity<String> httpEntity = new HttpEntity<>(null, headers);
|
||||
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
|
||||
RestTemplate restTemplate = new RestTemplate(factory);
|
||||
try {
|
||||
|
||||
return restTemplate.exchange(uri, HttpMethod.GET, httpEntity, byte[].class);
|
||||
|
||||
} catch (HttpStatusCodeException e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.err.println(e.getRawStatusCode());
|
||||
return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders())
|
||||
.body(e.getResponseBodyAsString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
server.port: 5000
|
||||
server.ssl.enabled: false
|
||||
|
||||
OPENVIDU_URL: https://demos.openvidu.io
|
||||
OPENVIDU_SECRET: MY_SECRET
|
||||
|
||||
RECORDING: ENABLED
|
||||
ADMIN_SECRET: MY_SECRET
|
||||
@ -0,0 +1,13 @@
|
||||
package io.openvidu.basic.java;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class AppTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user