mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: refactor Media Node selection
parent
e32b1f01b4
commit
d358562033
|
@ -46,7 +46,6 @@ import io.openvidu.client.OpenViduException;
|
|||
import io.openvidu.client.OpenViduException.Code;
|
||||
import io.openvidu.client.internal.ProtocolElements;
|
||||
import io.openvidu.java.client.ConnectionProperties;
|
||||
import io.openvidu.java.client.ConnectionType;
|
||||
import io.openvidu.java.client.KurentoOptions;
|
||||
import io.openvidu.java.client.OpenViduRole;
|
||||
import io.openvidu.java.client.Recording;
|
||||
|
@ -307,8 +306,8 @@ public abstract class SessionManager {
|
|||
log.error("Data invalid format");
|
||||
throw new OpenViduException(Code.GENERIC_ERROR_CODE, "Data invalid format");
|
||||
}
|
||||
Token tokenObj = tokenGenerator.generateToken(session.getSessionId(), serverMetadata,
|
||||
record, role, kurentoOptions);
|
||||
Token tokenObj = tokenGenerator.generateToken(session.getSessionId(), serverMetadata, record, role,
|
||||
kurentoOptions);
|
||||
session.storeToken(tokenObj);
|
||||
session.showTokens("Token created");
|
||||
return tokenObj;
|
||||
|
|
|
@ -78,13 +78,13 @@ public class KurentoSessionManager extends SessionManager {
|
|||
private static final Logger log = LoggerFactory.getLogger(KurentoSessionManager.class);
|
||||
|
||||
@Autowired
|
||||
private KmsManager kmsManager;
|
||||
protected KmsManager kmsManager;
|
||||
|
||||
@Autowired
|
||||
private KurentoSessionEventsHandler kurentoSessionEventsHandler;
|
||||
protected KurentoSessionEventsHandler kurentoSessionEventsHandler;
|
||||
|
||||
@Autowired
|
||||
private KurentoParticipantEndpointConfig kurentoEndpointConfig;
|
||||
protected KurentoParticipantEndpointConfig kurentoEndpointConfig;
|
||||
|
||||
@Override
|
||||
/* Protected by Session.closingLock.readLock */
|
||||
|
@ -110,23 +110,10 @@ public class KurentoSessionManager extends SessionManager {
|
|||
if (KmsManager.selectAndRemoveKmsLock.tryLock(KmsManager.MAX_SECONDS_LOCK_WAIT, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
kSession = (KurentoSession) sessions.get(sessionId);
|
||||
|
||||
if (kSession == null) {
|
||||
// Session still null. It was not created by other thread while waiting for lock
|
||||
Kms lessLoadedKms = null;
|
||||
try {
|
||||
lessLoadedKms = this.kmsManager.getLessLoadedConnectedAndRunningKms();
|
||||
} catch (NoSuchElementException e) {
|
||||
// Restore session not active
|
||||
this.cleanCollections(sessionId);
|
||||
this.storeSessionNotActive(sessionNotActive);
|
||||
throw new OpenViduException(Code.ROOM_CANNOT_BE_CREATED_ERROR_CODE,
|
||||
"There is no available Media Node where to initialize session '" + sessionId
|
||||
+ "'");
|
||||
}
|
||||
log.info("KMS less loaded is {} with a load of {}", lessLoadedKms.getUri(),
|
||||
lessLoadedKms.getLoad());
|
||||
kSession = createSession(sessionNotActive, lessLoadedKms);
|
||||
Kms selectedMediaNode = this.selectMediaNode(sessionNotActive);
|
||||
kSession = createSession(sessionNotActive, selectedMediaNode);
|
||||
}
|
||||
} finally {
|
||||
KmsManager.selectAndRemoveKmsLock.unlock();
|
||||
|
@ -992,8 +979,8 @@ public class KurentoSessionManager extends SessionManager {
|
|||
|
||||
@Override
|
||||
/* Protected by Session.closingLock.readLock */
|
||||
public Participant publishIpcam(Session session, MediaOptions mediaOptions, ConnectionProperties connectionProperties)
|
||||
throws Exception {
|
||||
public Participant publishIpcam(Session session, MediaOptions mediaOptions,
|
||||
ConnectionProperties connectionProperties) throws Exception {
|
||||
final String sessionId = session.getSessionId();
|
||||
final KurentoMediaOptions kMediaOptions = (KurentoMediaOptions) mediaOptions;
|
||||
|
||||
|
@ -1119,7 +1106,7 @@ public class KurentoSessionManager extends SessionManager {
|
|||
sessionEventsHandler.onVideoData(participant, transactionId, height, width, videoActive, audioActive);
|
||||
}
|
||||
|
||||
private void applyFilterInPublisher(KurentoParticipant kParticipant, KurentoFilter filter)
|
||||
protected void applyFilterInPublisher(KurentoParticipant kParticipant, KurentoFilter filter)
|
||||
throws OpenViduException {
|
||||
GenericMediaElement.Builder builder = new GenericMediaElement.Builder(kParticipant.getPipeline(),
|
||||
filter.getType());
|
||||
|
@ -1131,13 +1118,13 @@ public class KurentoSessionManager extends SessionManager {
|
|||
kParticipant.getPublisher().getMediaOptions().setFilter(filter);
|
||||
}
|
||||
|
||||
private void removeFilterInPublisher(KurentoParticipant kParticipant) {
|
||||
protected void removeFilterInPublisher(KurentoParticipant kParticipant) {
|
||||
kParticipant.getPublisher().cleanAllFilterListeners();
|
||||
kParticipant.getPublisher().revert(kParticipant.getPublisher().getFilter());
|
||||
kParticipant.getPublisher().getMediaOptions().setFilter(null);
|
||||
}
|
||||
|
||||
private KurentoFilter execFilterMethodInPublisher(KurentoParticipant kParticipant, String method,
|
||||
protected KurentoFilter execFilterMethodInPublisher(KurentoParticipant kParticipant, String method,
|
||||
JsonObject params) {
|
||||
kParticipant.getPublisher().execMethod(method, params);
|
||||
KurentoFilter filter = kParticipant.getPublisher().getMediaOptions().getFilter();
|
||||
|
@ -1146,7 +1133,7 @@ public class KurentoSessionManager extends SessionManager {
|
|||
return updatedFilter;
|
||||
}
|
||||
|
||||
private void addFilterEventListenerInPublisher(KurentoParticipant kParticipant, String eventType)
|
||||
protected void addFilterEventListenerInPublisher(KurentoParticipant kParticipant, String eventType)
|
||||
throws OpenViduException {
|
||||
PublisherEndpoint pub = kParticipant.getPublisher();
|
||||
if (!pub.isListenerAddedToFilterEvent(eventType)) {
|
||||
|
@ -1170,7 +1157,7 @@ public class KurentoSessionManager extends SessionManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void removeFilterEventListenerInPublisher(KurentoParticipant kParticipant, String eventType) {
|
||||
protected void removeFilterEventListenerInPublisher(KurentoParticipant kParticipant, String eventType) {
|
||||
PublisherEndpoint pub = kParticipant.getPublisher();
|
||||
if (pub.isListenerAddedToFilterEvent(eventType)) {
|
||||
GenericMediaElement filter = kParticipant.getPublisher().getFilter();
|
||||
|
@ -1178,4 +1165,19 @@ public class KurentoSessionManager extends SessionManager {
|
|||
}
|
||||
}
|
||||
|
||||
protected Kms selectMediaNode(Session session) throws OpenViduException {
|
||||
Kms lessLoadedKms = null;
|
||||
try {
|
||||
lessLoadedKms = this.kmsManager.getLessLoadedConnectedAndRunningKms();
|
||||
} catch (NoSuchElementException e) {
|
||||
// Restore session not active
|
||||
this.cleanCollections(session.getSessionId());
|
||||
this.storeSessionNotActive(session);
|
||||
throw new OpenViduException(Code.ROOM_CANNOT_BE_CREATED_ERROR_CODE,
|
||||
"There is no available Media Node where to initialize session '" + session + "'");
|
||||
}
|
||||
log.info("KMS less loaded is {} with a load of {}", lessLoadedKms.getUri(), lessLoadedKms.getLoad());
|
||||
return lessLoadedKms;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,80 +99,19 @@ public class SessionRestController {
|
|||
|
||||
log.info("REST API: POST {}/sessions {}", RequestMappings.API, params != null ? params.toString() : "{}");
|
||||
|
||||
SessionProperties.Builder builder = new SessionProperties.Builder();
|
||||
String customSessionId = null;
|
||||
|
||||
if (params != null) {
|
||||
|
||||
String mediaModeString;
|
||||
String recordingModeString;
|
||||
String defaultOutputModeString;
|
||||
String defaultRecordingLayoutString;
|
||||
String defaultCustomLayout;
|
||||
SessionProperties sessionProperties;
|
||||
try {
|
||||
mediaModeString = (String) params.get("mediaMode");
|
||||
recordingModeString = (String) params.get("recordingMode");
|
||||
defaultOutputModeString = (String) params.get("defaultOutputMode");
|
||||
defaultRecordingLayoutString = (String) params.get("defaultRecordingLayout");
|
||||
defaultCustomLayout = (String) params.get("defaultCustomLayout");
|
||||
customSessionId = (String) params.get("customSessionId");
|
||||
} catch (ClassCastException e) {
|
||||
return this.generateErrorResponse("Type error in some parameter", "/sessions", HttpStatus.BAD_REQUEST);
|
||||
sessionProperties = getSessionPropertiesFromParams(params).build();
|
||||
} catch (Exception e) {
|
||||
return this.generateErrorResponse(e.getMessage(), "/sessions", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
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 (defaultOutputModeString != null) {
|
||||
OutputMode defaultOutputMode = OutputMode.valueOf(defaultOutputModeString);
|
||||
builder = builder.defaultOutputMode(defaultOutputMode);
|
||||
} else {
|
||||
builder.defaultOutputMode(OutputMode.COMPOSED);
|
||||
}
|
||||
if (defaultRecordingLayoutString != null) {
|
||||
RecordingLayout defaultRecordingLayout = RecordingLayout.valueOf(defaultRecordingLayoutString);
|
||||
builder = builder.defaultRecordingLayout(defaultRecordingLayout);
|
||||
} else {
|
||||
builder.defaultRecordingLayout(RecordingLayout.BEST_FIT);
|
||||
}
|
||||
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)) {
|
||||
return this.generateErrorResponse(
|
||||
"Parameter 'customSessionId' is wrong. Must be an alphanumeric string [a-zA-Z0-9_-]",
|
||||
"/sessions", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
builder = builder.customSessionId(customSessionId);
|
||||
}
|
||||
builder = builder.defaultCustomLayout((defaultCustomLayout != null) ? defaultCustomLayout : "");
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
return this.generateErrorResponse("RecordingMode " + params.get("recordingMode") + " | "
|
||||
+ "Default OutputMode " + params.get("defaultOutputMode") + " | " + "Default RecordingLayout "
|
||||
+ params.get("defaultRecordingLayout") + " | " + "MediaMode " + params.get("mediaMode")
|
||||
+ ". Some parameter is not defined", "/sessions", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
SessionProperties sessionProperties = builder.build();
|
||||
|
||||
String sessionId;
|
||||
if (customSessionId != null && !customSessionId.isEmpty()) {
|
||||
if (sessionManager.getSessionWithNotActive(customSessionId) != null) {
|
||||
if (sessionProperties.customSessionId() != null && !sessionProperties.customSessionId().isEmpty()) {
|
||||
if (sessionManager.getSessionWithNotActive(sessionProperties.customSessionId()) != null) {
|
||||
return new ResponseEntity<>(HttpStatus.CONFLICT);
|
||||
}
|
||||
sessionId = customSessionId;
|
||||
sessionId = sessionProperties.customSessionId();
|
||||
} else {
|
||||
sessionId = IdentifierPrefixes.SESSION_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
|
||||
+ RandomStringUtils.randomAlphanumeric(9);
|
||||
|
@ -846,17 +785,76 @@ public class SessionRestController {
|
|||
}
|
||||
}
|
||||
|
||||
protected Token getTokenFromConnectionId(String connectionId, Iterator<Entry<String, Token>> iterator) {
|
||||
boolean found = false;
|
||||
Token token = null;
|
||||
while (iterator.hasNext() && !found) {
|
||||
Token tAux = iterator.next().getValue();
|
||||
found = tAux.getConnectionId().equals(connectionId);
|
||||
if (found) {
|
||||
token = tAux;
|
||||
protected SessionProperties.Builder getSessionPropertiesFromParams(Map<?, ?> params) throws Exception {
|
||||
|
||||
SessionProperties.Builder builder = new SessionProperties.Builder();
|
||||
String customSessionId = null;
|
||||
|
||||
if (params != null) {
|
||||
|
||||
String mediaModeString;
|
||||
String recordingModeString;
|
||||
String defaultOutputModeString;
|
||||
String defaultRecordingLayoutString;
|
||||
String defaultCustomLayout;
|
||||
try {
|
||||
mediaModeString = (String) params.get("mediaMode");
|
||||
recordingModeString = (String) params.get("recordingMode");
|
||||
defaultOutputModeString = (String) params.get("defaultOutputMode");
|
||||
defaultRecordingLayoutString = (String) params.get("defaultRecordingLayout");
|
||||
defaultCustomLayout = (String) params.get("defaultCustomLayout");
|
||||
customSessionId = (String) params.get("customSessionId");
|
||||
} catch (ClassCastException e) {
|
||||
throw new Exception("Type error in some parameter: " + 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 (defaultOutputModeString != null) {
|
||||
OutputMode defaultOutputMode = OutputMode.valueOf(defaultOutputModeString);
|
||||
builder = builder.defaultOutputMode(defaultOutputMode);
|
||||
} else {
|
||||
builder.defaultOutputMode(OutputMode.COMPOSED);
|
||||
}
|
||||
if (defaultRecordingLayoutString != null) {
|
||||
RecordingLayout defaultRecordingLayout = RecordingLayout.valueOf(defaultRecordingLayoutString);
|
||||
builder = builder.defaultRecordingLayout(defaultRecordingLayout);
|
||||
} else {
|
||||
builder.defaultRecordingLayout(RecordingLayout.BEST_FIT);
|
||||
}
|
||||
if (defaultCustomLayout != null) {
|
||||
builder.defaultCustomLayout(defaultCustomLayout);
|
||||
} else {
|
||||
builder.defaultCustomLayout("");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Exception("RecordingMode " + params.get("recordingMode") + " | " + "Default OutputMode "
|
||||
+ params.get("defaultOutputMode") + " | " + "Default RecordingLayout "
|
||||
+ params.get("defaultRecordingLayout") + " | " + "MediaMode " + params.get("mediaMode")
|
||||
+ ". Some parameter is not defined");
|
||||
}
|
||||
}
|
||||
return token;
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected ConnectionProperties.Builder getConnectionPropertiesFromParams(Map<?, ?> params) throws Exception {
|
||||
|
@ -975,6 +973,19 @@ public class SessionRestController {
|
|||
return builder;
|
||||
}
|
||||
|
||||
protected Token getTokenFromConnectionId(String connectionId, Iterator<Entry<String, Token>> iterator) {
|
||||
boolean found = false;
|
||||
Token token = null;
|
||||
while (iterator.hasNext() && !found) {
|
||||
Token tAux = iterator.next().getValue();
|
||||
found = tAux.getConnectionId().equals(connectionId);
|
||||
if (found) {
|
||||
token = tAux;
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
protected ResponseEntity<String> generateErrorResponse(String errorMessage, String path, HttpStatus status) {
|
||||
JsonObject responseJson = new JsonObject();
|
||||
responseJson.addProperty("timestamp", System.currentTimeMillis());
|
||||
|
|
Loading…
Reference in New Issue