add message count limitation to device session

revert-dabc3590
warunalakshitha 7 years ago
parent b407287b7c
commit 17cdb1652b

@ -23,10 +23,11 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId> <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId> <artifactId>remote-session-extension</artifactId>
<version>4.0.35-SNAPSHOT</version> <version>4.0.54-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.extensions.remote.session.endpoint</artifactId> <artifactId>org.wso2.carbon.device.mgt.extensions.remote.session.endpoint</artifactId>
<packaging>war</packaging> <packaging>war</packaging>

@ -43,8 +43,6 @@ import java.io.IOException;
public class ClientSessionSubscriptionEndpoint extends SubscriptionEndpoint { public class ClientSessionSubscriptionEndpoint extends SubscriptionEndpoint {
private static final Log log = LogFactory.getLog(ClientSessionSubscriptionEndpoint.class); private static final Log log = LogFactory.getLog(ClientSessionSubscriptionEndpoint.class);
private RemoteSessionConstants.CONNECTION_MODES connectionMode = RemoteSessionConstants.CONNECTION_MODES.CLIENT_MODE;
/** /**
* Web socket onOpen - When client sends a message * Web socket onOpen - When client sends a message
* *

@ -43,8 +43,6 @@ import java.io.IOException;
public class DeviceSessionSubscriptionEndpoint extends SubscriptionEndpoint { public class DeviceSessionSubscriptionEndpoint extends SubscriptionEndpoint {
private static final Log log = LogFactory.getLog(DeviceSessionSubscriptionEndpoint.class); private static final Log log = LogFactory.getLog(DeviceSessionSubscriptionEndpoint.class);
private RemoteSessionConstants.CONNECTION_MODES connectionMode = RemoteSessionConstants.CONNECTION_MODES.DEVICE_MODE;
/** /**
* Web socket onOpen - When client sends a message * Web socket onOpen - When client sends a message
* *

@ -108,9 +108,6 @@ public class SubscriptionEndpoint {
} }
try { try {
ServiceHolder.getInstance().getRemoteSessionManagementService().endSession(session); ServiceHolder.getInstance().getRemoteSessionManagementService().endSession(session);
if (session.isOpen()) {
session.close(new CloseReason(CloseReason.CloseCodes.PROTOCOL_ERROR, "Unexpected Error Occurred"));
}
} catch (IOException ex) { } catch (IOException ex) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.error("Failed to disconnect the client.", ex); log.error("Failed to disconnect the client.", ex);

@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId> <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId> <artifactId>remote-session-extension</artifactId>
<version>4.0.35-SNAPSHOT</version> <version>4.0.54-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

@ -21,6 +21,7 @@ import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSess
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionManagementException; import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionManagementException;
import javax.websocket.Session; import javax.websocket.Session;
import java.io.IOException;
/** /**
* Class @{@link RemoteSessionManagementService} use for managing remote sessions * Class @{@link RemoteSessionManagementService} use for managing remote sessions
@ -40,7 +41,7 @@ public interface RemoteSessionManagementService {
RemoteSessionInvalidException, RemoteSessionManagementException; RemoteSessionInvalidException, RemoteSessionManagementException;
/** /**
* Initialize session based on web socket request .this method use by the device to connect * Initialize session based on web socket request . This method use by the device to connect
* *
* @param session Web socket RemoteSession * @param session Web socket RemoteSession
* @param deviceType Device Type * @param deviceType Device Type
@ -79,6 +80,6 @@ public interface RemoteSessionManagementService {
* *
* @param session Web socket RemoteSession * @param session Web socket RemoteSession
*/ */
public void endSession(Session session); public void endSession(Session session) throws IOException;
} }

@ -33,13 +33,16 @@ import org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation;
import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.AuthenticationInfo; import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.AuthenticationInfo;
import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator; import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator;
import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants; import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.RemoteSession; import org.wso2.carbon.device.mgt.extensions.remote.session.dto.ClientSession;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.DeviceSession;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.common.RemoteSession;
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionInvalidException; import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionInvalidException;
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionManagementException; import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionManagementException;
import org.wso2.carbon.device.mgt.extensions.remote.session.internal.RemoteSessionManagementDataHolder; import org.wso2.carbon.device.mgt.extensions.remote.session.internal.RemoteSessionManagementDataHolder;
import javax.websocket.CloseReason; import javax.websocket.CloseReason;
import javax.websocket.Session; import javax.websocket.Session;
import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -69,6 +72,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
List<String> sessionQueryParamList = new LinkedList<>(); List<String> sessionQueryParamList = new LinkedList<>();
sessionQueryParamList.add(session.getQueryString()); sessionQueryParamList.add(session.getQueryString());
sessionQueryParam.put(RemoteSessionConstants.QUERY_STRING, sessionQueryParamList); sessionQueryParam.put(RemoteSessionConstants.QUERY_STRING, sessionQueryParamList);
// Validate the token // Validate the token
OAuthAuthenticator oAuthAuthenticator = RemoteSessionManagementDataHolder.getInstance().getOauthAuthenticator(); OAuthAuthenticator oAuthAuthenticator = RemoteSessionManagementDataHolder.getInstance().getOauthAuthenticator();
AuthenticationInfo authenticationInfo = oAuthAuthenticator.isAuthenticated(sessionQueryParam); AuthenticationInfo authenticationInfo = oAuthAuthenticator.isAuthenticated(sessionQueryParam);
@ -84,12 +88,19 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId); deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(deviceType); deviceIdentifier.setType(deviceType);
// Check authorization for user
boolean userAuthorized = RemoteSessionManagementDataHolder.getInstance() boolean userAuthorized = RemoteSessionManagementDataHolder.getInstance()
.getDeviceAccessAuthorizationService() .getDeviceAccessAuthorizationService()
.isUserAuthorized(deviceIdentifier, authenticationInfo.getUsername()); .isUserAuthorized(deviceIdentifier, authenticationInfo.getUsername());
if (userAuthorized) { if (userAuthorized) {
log.info("Operation ID: " + operationId); log.info("Operation ID: " + operationId);
// set common settings for session
session.setMaxBinaryMessageBufferSize(MAX_BUFFER_SIZE);
session.setMaxTextMessageBufferSize(MAX_BUFFER_SIZE);
session.setMaxIdleTimeout(RemoteSessionManagementDataHolder.getInstance().getMaxIdleTimeout());
// if session initiated using operatiod id means request came from device
if (operationId != null) { if (operationId != null) {
Session pendingSession = RemoteSessionManagementDataHolder.getInstance() Session pendingSession = RemoteSessionManagementDataHolder.getInstance()
.getDeviceRequestMap().get((authenticationInfo.getTenantDomain() + "/" + deviceType .getDeviceRequestMap().get((authenticationInfo.getTenantDomain() + "/" + deviceType
@ -101,11 +112,10 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
if (clientRemote != null) { if (clientRemote != null) {
if (clientRemote.getOperationId().equals(operationId)) { if (clientRemote.getOperationId().equals(operationId)) {
RemoteSession deviceRemote = new RemoteSession(authenticationInfo.getTenantDomain RemoteSession deviceRemote = new DeviceSession(session, authenticationInfo
(), deviceType, deviceId, operationId, RemoteSessionConstants .getTenantDomain(), deviceType, deviceId, operationId);
.CONNECTION_MODES.DEVICE_MODE); deviceRemote.setPeerSession(clientRemote);
deviceRemote.setPeerSession(pendingSession); clientRemote.setPeerSession(deviceRemote);
clientRemote.setPeerSession(session);
RemoteSessionManagementDataHolder.getInstance().getSessionMap().put(session RemoteSessionManagementDataHolder.getInstance().getSessionMap().put(session
.getId(), deviceRemote); .getId(), deviceRemote);
RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().remove( RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().remove(
@ -115,9 +125,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
message.put("code", RemoteSessionConstants.REMOTE_CONNECT); message.put("code", RemoteSessionConstants.REMOTE_CONNECT);
message.put("operation_response", "connected"); message.put("operation_response", "connected");
deviceRemote.sendMessageToPeer(message.toString()); deviceRemote.sendMessageToPeer(message.toString());
// set buffer sizes
session.setMaxBinaryMessageBufferSize(MAX_BUFFER_SIZE);
session.setMaxTextMessageBufferSize(MAX_BUFFER_SIZE);
} else { } else {
throw new RemoteSessionManagementException("Device and Operation information does" + throw new RemoteSessionManagementException("Device and Operation information does" +
" not matched with client information for operation id: " + operationId + " not matched with client information for operation id: " + operationId +
@ -136,6 +144,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
"id: " + operationId + " device Type : " + deviceType + " , " + "deviceId : " + "id: " + operationId + " device Type : " + deviceType + " , " + "deviceId : " +
deviceId); deviceId);
} }
} else { } else {
// Create new remote control operation to start the session // Create new remote control operation to start the session
Session pendingSession = RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().get( Session pendingSession = RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().get(
@ -148,27 +157,29 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
session); session);
if (lastSession == null) { if (lastSession == null) {
// Create operation if session initiated by client
Operation operation = new ConfigOperation(); Operation operation = new ConfigOperation();
operation.setCode(RemoteSessionConstants.REMOTE_CONNECT); operation.setCode(RemoteSessionConstants.REMOTE_CONNECT);
operation.setEnabled(true); operation.setEnabled(true);
operation.setControl(Operation.Control.NO_REPEAT);
JSONObject payload = new JSONObject(); JSONObject payload = new JSONObject();
payload.put("serverUrl", RemoteSessionManagementDataHolder.getInstance().getServerUrl()); payload.put("serverUrl", RemoteSessionManagementDataHolder.getInstance().getServerUrl());
operation.setPayLoad(payload.toString()); operation.setPayLoad(payload.toString());
String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date()); String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date());
operation.setCreatedTimeStamp(date); operation.setCreatedTimeStamp(date);
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>(); List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
deviceIdentifiers.add(new DeviceIdentifier(deviceId, deviceType)); deviceIdentifiers.add(new DeviceIdentifier(deviceId, deviceType));
Activity activity = RemoteSessionManagementDataHolder.getInstance() Activity activity = RemoteSessionManagementDataHolder.getInstance()
.getDeviceManagementProviderService().addOperation(deviceType, operation, .getDeviceManagementProviderService().addOperation(deviceType, operation,
deviceIdentifiers); deviceIdentifiers);
log.info("Activity id: " + activity.getActivityId()); log.info("Activity id: " + activity.getActivityId());
RemoteSession clientRemote = new RemoteSession(authenticationInfo.getTenantDomain(),
deviceType, deviceId, activity.getActivityId().replace(DeviceManagementConstants RemoteSession clientRemote = new ClientSession(session, authenticationInfo
.OperationAttributes.ACTIVITY, ""), RemoteSessionConstants .getTenantDomain(), deviceType, deviceId, activity.getActivityId().replace(DeviceManagementConstants
.CONNECTION_MODES.CLIENT_MODE); .OperationAttributes.ACTIVITY, ""));
RemoteSessionManagementDataHolder.getInstance().getSessionMap().put(session.getId(), clientRemote); RemoteSessionManagementDataHolder.getInstance().getSessionMap().put(session.getId(), clientRemote);
session.setMaxBinaryMessageBufferSize(MAX_BUFFER_SIZE);
session.setMaxTextMessageBufferSize(MAX_BUFFER_SIZE);
} }
} }
} }
@ -209,7 +220,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
* Implements the behaviour of sending message to peer connection * Implements the behaviour of sending message to peer connection
* *
* @param session Web socket RemoteSession * @param session Web socket RemoteSession
* @param message Message needs to send to peer connection * @param message String message needs to send to peer connection
* @throws RemoteSessionInvalidException throws when session cannot be made due to invalid data * @throws RemoteSessionInvalidException throws when session cannot be made due to invalid data
* @throws RemoteSessionManagementException throws when session has error with accessing device resources * @throws RemoteSessionManagementException throws when session has error with accessing device resources
*/ */
@ -219,7 +230,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
JSONObject jsonObject = new JSONObject(message); JSONObject jsonObject = new JSONObject(message);
RemoteSession remoteSession = RemoteSessionManagementDataHolder.getInstance().getSessionMap().get(session.getId()); RemoteSession remoteSession = RemoteSessionManagementDataHolder.getInstance().getSessionMap().get(session.getId());
if (remoteSession != null) { if (remoteSession != null) {
if (remoteSession.getConnection_mode().equals(RemoteSessionConstants.CONNECTION_MODES.CLIENT_MODE)) { if (remoteSession instanceof ClientSession) {
jsonObject.put("id", remoteSession.getOperationId()); jsonObject.put("id", remoteSession.getOperationId());
} }
remoteSession.sendMessageToPeer(jsonObject.toString()); remoteSession.sendMessageToPeer(jsonObject.toString());
@ -230,6 +241,14 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
} }
/**
* Implements the behaviour of sending message to peer connection
*
* @param session Web socket RemoteSession
* @param message Byte message needs to send to peer connection
* @throws RemoteSessionInvalidException throws when session cannot be made due to invalid data
* @throws RemoteSessionManagementException throws when session has error with accessing device resources
*/
@Override @Override
public void sendMessageToPeer(Session session, byte[] message) throws RemoteSessionInvalidException, public void sendMessageToPeer(Session session, byte[] message) throws RemoteSessionInvalidException,
RemoteSessionManagementException { RemoteSessionManagementException {
@ -249,14 +268,17 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
* @param session Web socket RemoteSession * @param session Web socket RemoteSession
*/ */
@Override @Override
public void endSession(Session session) { public void endSession(Session session) throws IOException {
RemoteSession remoteSession = RemoteSessionManagementDataHolder.getInstance().getSessionMap().remove(session.getId()); RemoteSession remoteSession = RemoteSessionManagementDataHolder.getInstance().getSessionMap().remove(session.getId());
if (remoteSession != null) { if (remoteSession != null) {
String operationId = remoteSession.getOperationId(); String operationId = remoteSession.getOperationId();
Session peerSession = remoteSession.getPeerSession(); Session peerSession = remoteSession.getPeerSession().getMySession();
if (peerSession != null) { if (peerSession != null) {
RemoteSessionManagementDataHolder.getInstance().getSessionMap().remove(peerSession.getId()); RemoteSessionManagementDataHolder.getInstance().getSessionMap().remove(peerSession.getId());
if (peerSession.isOpen()) {
peerSession.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Remote session closed"));
}
} }
if (operationId != null) { if (operationId != null) {
Session lastSession = RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().get( Session lastSession = RemoteSessionManagementDataHolder.getInstance().getDeviceRequestMap().get(

@ -20,6 +20,9 @@ import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.oauth
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
* {@link OAuthAuthenticator} for validate tokens to web socket api
*/
public class OAuthAuthenticator { public class OAuthAuthenticator {
OAuthTokenValidator oAuthTokenValidator; OAuthTokenValidator oAuthTokenValidator;

@ -24,24 +24,18 @@ package org.wso2.carbon.device.mgt.extensions.remote.session.constants;
public class RemoteSessionConstants { public class RemoteSessionConstants {
public static final String SCOPE_IDENTIFIER = "scopes"; public static final String SCOPE_IDENTIFIER = "scopes";
public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection";
public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost";
public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationUrl"; public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationUrl";
public static final String TOKEN_VALIDATION_CONTEX = "/services/OAuth2TokenValidationService"; public static final String TOKEN_VALIDATION_CONTEX = "/services/OAuth2TokenValidationService";
public static final String USERNAME = "username"; public static final String USERNAME = "username";
public static final String PASSWORD = "password"; public static final String PASSWORD = "password";
public static final String DEVICE_ID = "deviceId";
public static final String DEVICE_TYPE = "deviceType";
public static final String REMOTE_CONNECT = "REMOTE_CONNECT"; public static final String REMOTE_CONNECT = "REMOTE_CONNECT";
public static final String THROTTLE_OUT = "THROTTLE_OUT";
public static final String QUERY_STRING = "queryString"; public static final String QUERY_STRING = "queryString";
public static final String OPERATION_CODE = "operation_code"; public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection";
public static final String REMOTE_SESSION_DEVICE_ENDPOINT_CONTEXT = "/remote/session/devices"; public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost";
public static final String DEFAULT_MAXIMUM_HTTP_CONNECTION_PER_HOST = "2";
// Constants for remote session Connection modes public static final String DEFAULT_MAXIMUM_TOTAL_HTTP_CONNECTIONS = "100";
public enum CONNECTION_MODES {
CLIENT_MODE, DEVICE_MODE
}
private RemoteSessionConstants() { private RemoteSessionConstants() {
} }

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.remote.session.dto;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.common.RemoteSession;
import javax.websocket.Session;
/**
* {@link ClientSession} is the represent of client which will be connecting to the device
*/
public class ClientSession extends RemoteSession {
public ClientSession(Session session, String tenantDomain, String deviceType, String deviceId, String operationId) {
super(session, tenantDomain, deviceType, deviceId, operationId);
}
@Override
public boolean applyThrottlingPolicy() {
return false;
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.remote.session.dto;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.common.RemoteSession;
import org.wso2.carbon.device.mgt.extensions.remote.session.internal.RemoteSessionManagementDataHolder;
import javax.websocket.Session;
/**
* {@link DeviceSession} is the represent of device which will be connecting based on client request
*/
public class DeviceSession extends RemoteSession {
public DeviceSession(Session session, String tenantDomain, String deviceType, String deviceId, String operationId) {
super(session, tenantDomain, deviceType, deviceId, operationId);
}
@Override
public boolean applyThrottlingPolicy() {
if (RemoteSessionManagementDataHolder.getInstance().getMessagesPerSession() > 0) {
long minDurationMessagesPerSecond = 1000 / RemoteSessionManagementDataHolder.getInstance()
.getMessagesPerSession();
if ((System.currentTimeMillis() - getLastMessageTimeStamp()) < minDurationMessagesPerSecond) {
return true;
}
}
return false;
}
}

@ -1,125 +0,0 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.remote.session.dto;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants;
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionInvalidException;
import javax.websocket.CloseReason;
import javax.websocket.Session;
import java.io.IOException;
import java.nio.ByteBuffer;
public class RemoteSession {
private static final Log log = LogFactory.getLog(RemoteSession.class);
private String tenantDomain, operationId, deviceType, deviceId;
private Session peerSession;
private RemoteSessionConstants.CONNECTION_MODES connection_mode;
private final Object writeLockObject = new Object();
public RemoteSession(String tenantDomain, String deviceType, String deviceId, String operationId, RemoteSessionConstants.CONNECTION_MODES connection_mode) {
this.deviceType = deviceType;
this.deviceId = deviceId;
this.tenantDomain = tenantDomain;
this.operationId = operationId;
this.connection_mode = connection_mode;
}
public void sendMessageToPeer(String message) throws RemoteSessionInvalidException {
if (peerSession != null && peerSession.isOpen()) {
synchronized (writeLockObject) {
try {
peerSession.getBasicRemote().sendText(message);
} catch (IOException e) {
log.warn("Send data to session failed due to ", e);
}
}
} else {
throw new RemoteSessionInvalidException("Peer Session already closed ", new CloseReason
(CloseReason.CloseCodes.CANNOT_ACCEPT, "Peer Session already closed "));
}
}
public void sendMessageToPeer(byte[] message) throws RemoteSessionInvalidException {
if (peerSession != null && peerSession.isOpen()) {
synchronized (writeLockObject) {
try {
peerSession.getBasicRemote().sendBinary(ByteBuffer.wrap(message));
} catch (IOException e) {
log.warn("Send data to session failed due to ", e);
}
}
} else {
throw new RemoteSessionInvalidException("Peer Session already closed ", new CloseReason
(CloseReason.CloseCodes.CANNOT_ACCEPT, "Peer Session already closed "));
}
}
public Session getPeerSession() {
return peerSession;
}
public void setPeerSession(Session peerSession) {
this.peerSession = peerSession;
}
public String getTenantDomain() {
return tenantDomain;
}
public void setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
}
public String getOperationId() {
return operationId;
}
public void setOperationId(String operationId) {
this.operationId = operationId;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public RemoteSessionConstants.CONNECTION_MODES getConnection_mode() {
return connection_mode;
}
public void setConnection_mode(RemoteSessionConstants.CONNECTION_MODES connection_mode) {
this.connection_mode = connection_mode;
}
}

@ -0,0 +1,154 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.extensions.remote.session.dto.common;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants;
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionInvalidException;
import org.wso2.carbon.device.mgt.extensions.remote.session.exception.RemoteSessionManagementException;
import javax.websocket.CloseReason;
import javax.websocket.Session;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* {@link RemoteSession} will represent remote websocket session
* This class implements the behaviours of sending message to the session in multithreaded environment.
*
*/
public abstract class RemoteSession {
private static final Log log = LogFactory.getLog(RemoteSession.class);
private String tenantDomain, operationId, deviceType, deviceId;
private long lastMessageTimeStamp = System.currentTimeMillis();
;
private RemoteSession peerSession;
private Session mySession;
private final Object writeLockObject = new Object();
protected RemoteSession(Session session, String tenantDomain, String deviceType, String deviceId, String
operationId) {
this.mySession = session;
this.deviceType = deviceType;
this.deviceId = deviceId;
this.tenantDomain = tenantDomain;
this.operationId = operationId;
}
public void sendMessage(Object message) throws RemoteSessionInvalidException, RemoteSessionManagementException {
if (message != null) {
boolean isMessageCountExceed = false;
if (mySession != null && mySession.isOpen()) {
synchronized (writeLockObject) {
try {
isMessageCountExceed = applyThrottlingPolicy();
if (!isMessageCountExceed) {
if (message instanceof String) {
mySession.getBasicRemote().sendText(message.toString());
} else {
mySession.getBasicRemote().sendBinary(ByteBuffer.wrap((byte[]) message));
}
this.lastMessageTimeStamp = System.currentTimeMillis();
}
} catch (IOException e) {
log.warn("Send data to session failed due to ", e);
}
}
} else {
throw new RemoteSessionInvalidException("Peer Session already closed ", new CloseReason
(CloseReason.CloseCodes.CANNOT_ACCEPT, "Peer Session already closed "));
}
if (isMessageCountExceed) {
JSONObject response = new JSONObject();
response.put("code", RemoteSessionConstants.THROTTLE_OUT);
sendMessageToPeer(message.toString());
}
} else {
throw new RemoteSessionManagementException("Message is empty");
}
}
public void sendMessageToPeer(Object message) throws RemoteSessionInvalidException, RemoteSessionManagementException {
peerSession.sendMessage(message);
}
public abstract boolean applyThrottlingPolicy();
public Session getMySession() {
return mySession;
}
public void setMySession(Session mySession) {
this.mySession = mySession;
}
public RemoteSession getPeerSession() {
return peerSession;
}
public void setPeerSession(RemoteSession peerSession) {
this.peerSession = peerSession;
}
public String getTenantDomain() {
return tenantDomain;
}
public void setTenantDomain(String tenantDomain) {
this.tenantDomain = tenantDomain;
}
public String getOperationId() {
return operationId;
}
public void setOperationId(String operationId) {
this.operationId = operationId;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public long getLastMessageTimeStamp() {
return lastMessageTimeStamp;
}
public void setLastMessageTimeStamp(long lastMessageTimeStamp) {
this.lastMessageTimeStamp = lastMessageTimeStamp;
}
}

@ -19,10 +19,9 @@
package org.wso2.carbon.device.mgt.extensions.remote.session.internal; package org.wso2.carbon.device.mgt.extensions.remote.session.internal;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator; import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator;
import org.wso2.carbon.device.mgt.extensions.remote.session.dto.RemoteSession; import org.wso2.carbon.device.mgt.extensions.remote.session.dto.common.RemoteSession;
import javax.websocket.Session; import javax.websocket.Session;
import java.util.Map; import java.util.Map;
@ -35,6 +34,8 @@ public class RemoteSessionManagementDataHolder {
private DeviceAccessAuthorizationService deviceAccessAuthorizationService; private DeviceAccessAuthorizationService deviceAccessAuthorizationService;
private boolean isEnabled; private boolean isEnabled;
private String serverUrl; private String serverUrl;
private long maxIdleTimeout;
private int messagesPerSession;
private OAuthAuthenticator oAuthAuthenticator; private OAuthAuthenticator oAuthAuthenticator;
private Map<String, Session> deviceRequestMap = new ConcurrentHashMap<String, Session>(); private Map<String, Session> deviceRequestMap = new ConcurrentHashMap<String, Session>();
private Map<String, RemoteSession> sessionMap = new ConcurrentHashMap<String, RemoteSession>(); private Map<String, RemoteSession> sessionMap = new ConcurrentHashMap<String, RemoteSession>();
@ -98,4 +99,20 @@ public class RemoteSessionManagementDataHolder {
public void setServerUrl(String serverUrl) { public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl; this.serverUrl = serverUrl;
} }
public int getMessagesPerSession() {
return messagesPerSession;
}
public void setMessagesPerSession(int messagesPerSession) {
this.messagesPerSession = messagesPerSession;
}
public long getMaxIdleTimeout() {
return maxIdleTimeout;
}
public void setMaxIdleTimeout(long maxIdleTimeout) {
this.maxIdleTimeout = maxIdleTimeout;
}
} }

@ -23,7 +23,8 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations;
import org.wso2.carbon.device.mgt.core.config.remote.session.RemoteSessionConfiguration;
import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator; import org.wso2.carbon.device.mgt.extensions.remote.session.authentication.OAuthAuthenticator;
import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants; import org.wso2.carbon.device.mgt.extensions.remote.session.constants.RemoteSessionConstants;
import org.wso2.carbon.device.mgt.extensions.remote.session.internal.RemoteSessionManagementDataHolder; import org.wso2.carbon.device.mgt.extensions.remote.session.internal.RemoteSessionManagementDataHolder;
@ -33,8 +34,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* Startup listener is been used to make sure the reciever gets activated after the server start up to avoid * Startup listener is been used to make sure the receiver gets activated after the server start up to avoid
* Bundle not loading issues. * Bundle not loading issues.
* This will configure the values for remote session management
*/ */
public class RemoteSessionManagerStartupListener implements ServerStartupObserver { public class RemoteSessionManagerStartupListener implements ServerStartupObserver {
@ -50,18 +52,41 @@ public class RemoteSessionManagerStartupListener implements ServerStartupObserve
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
try { try {
RemoteSessionConfiguration rsConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig
().getRemoteSessionConfiguration();
KeyManagerConfigurations kmConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getKeyManagerConfigurations();
RemoteSessionManagementDataHolder.getInstance().setEnabled(DeviceConfigurationManager.getInstance() RemoteSessionManagementDataHolder.getInstance().setEnabled(rsConfig.isEnabled());
.getDeviceManagementConfig().getRemoteSessionConfiguration().getIsEnabled()); RemoteSessionManagementDataHolder.getInstance().setServerUrl(rsConfig.getRemoteSessionServerUrl());
RemoteSessionManagementDataHolder.getInstance().setServerUrl(DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig().getRemoteSessionConfiguration().getRemoteSessionServerUrl());
Map<String, String> configProperties = new HashMap<>(); Map<String, String> configProperties = new HashMap<>();
configProperties.put(RemoteSessionConstants.TOKEN_VALIDATION_ENDPOINT_URL, "https://localhost:9443");
configProperties.put(RemoteSessionConstants.USERNAME,"admin"); // Set max idle timeout in milliseconds
configProperties.put(RemoteSessionConstants.PASSWORD,"admin"); RemoteSessionManagementDataHolder.getInstance().setMaxIdleTimeout(rsConfig.getSessionIdleTimeOut()*60000);
configProperties.put(RemoteSessionConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST,"2");
configProperties.put(RemoteSessionConstants.MAXIMUM_TOTAL_HTTP_CONNECTION,"100"); // Set max messages per second.
OAuthAuthenticator oAuthAuthenticator= new OAuthAuthenticator(); RemoteSessionManagementDataHolder.getInstance().setMessagesPerSession(rsConfig.getMaxMessagesPerSession());
// Token validation related configuration
configProperties.put(RemoteSessionConstants.TOKEN_VALIDATION_ENDPOINT_URL, kmConfig.getServerUrl());
configProperties.put(RemoteSessionConstants.USERNAME, kmConfig.getAdminUsername());
configProperties.put(RemoteSessionConstants.PASSWORD, kmConfig.getAdminPassword());
if (rsConfig.getMaxHTTPConnectionPerHost() > 0) {
configProperties.put(RemoteSessionConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST,
String.valueOf(rsConfig.getMaxHTTPConnectionPerHost()));
} else {
configProperties.put(RemoteSessionConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST, RemoteSessionConstants
.DEFAULT_MAXIMUM_HTTP_CONNECTION_PER_HOST);
}
if (rsConfig.getMaxTotalHTTPConnections() > 0) {
configProperties.put(RemoteSessionConstants.MAXIMUM_TOTAL_HTTP_CONNECTION, String.valueOf(rsConfig
.getMaxTotalHTTPConnections()));
} else {
configProperties.put(RemoteSessionConstants.MAXIMUM_TOTAL_HTTP_CONNECTION, RemoteSessionConstants
.DEFAULT_MAXIMUM_TOTAL_HTTP_CONNECTIONS);
}
OAuthAuthenticator oAuthAuthenticator = new OAuthAuthenticator();
oAuthAuthenticator.init(configProperties); oAuthAuthenticator.init(configProperties);
RemoteSessionManagementDataHolder.getInstance().setOauthAuthenticator(oAuthAuthenticator); RemoteSessionManagementDataHolder.getInstance().setOauthAuthenticator(oAuthAuthenticator);

@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId> <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId> <artifactId>extensions</artifactId>
<version>4.0.35-SNAPSHOT</version> <version>4.0.54-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

@ -3,14 +3,14 @@
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId> <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions-feature</artifactId> <artifactId>extensions-feature</artifactId>
<version>4.0.35-SNAPSHOT</version> <version>4.0.54-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.remote.session.feature</artifactId> <artifactId>org.wso2.carbon.device.mgt.remote.session.feature</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>4.0.35-SNAPSHOT</version> <version>4.0.54-SNAPSHOT</version>
<name>WSO2 Carbon - Remote Session Manager</name> <name>WSO2 Carbon - Remote Session Manager</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<description>This feature contains the core bundles required iot Remote Sessions</description> <description>This feature contains the core bundles required iot Remote Sessions</description>
@ -55,7 +55,7 @@
<outputDirectory> <outputDirectory>
${project.build.directory}/maven-shared-archive-resources/webapps/ ${project.build.directory}/maven-shared-archive-resources/webapps/
</outputDirectory> </outputDirectory>
<destFileName>remote-session.war</destFileName> <destFileName>remote#session.war</destFileName>
</artifactItem> </artifactItem>
</artifactItems> </artifactItems>
</configuration> </configuration>

Loading…
Cancel
Save