mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Ticket #263: Refactored ActiveConnectionMap and added group load balancing.
This commit is contained in:
@@ -0,0 +1,283 @@
|
|||||||
|
|
||||||
|
package net.sourceforge.guacamole.net.auth.mysql;
|
||||||
|
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (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.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is guacamole-auth-mysql.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* James Muehlner.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.sourceforge.guacamole.GuacamoleException;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the map of currently active Connections to the count of the number
|
||||||
|
* of current users. Whenever a socket is opened, the connection count should be
|
||||||
|
* incremented, and whenever a socket is closed, the connection count should be
|
||||||
|
* decremented.
|
||||||
|
*
|
||||||
|
* @author James Muehlner
|
||||||
|
*/
|
||||||
|
public class ActiveConnectionMap {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the count of users currently using a MySQL connection.
|
||||||
|
*/
|
||||||
|
public class Connection implements Comparable<Connection> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of the MySQL connection that this Connection represents.
|
||||||
|
*/
|
||||||
|
private int connectionID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of users currently using this connection.
|
||||||
|
*/
|
||||||
|
private int currentUserCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of the MySQL connection that this Connection
|
||||||
|
* represents.
|
||||||
|
*
|
||||||
|
* @return the ID of the MySQL connection that this Connection
|
||||||
|
* represents.
|
||||||
|
*/
|
||||||
|
public int getConnectionID() {
|
||||||
|
return connectionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of users currently using this connection.
|
||||||
|
*
|
||||||
|
* @return the number of users currently using this connection.
|
||||||
|
*/
|
||||||
|
public int getCurrentUserCount() {
|
||||||
|
return currentUserCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current user count for this connection.
|
||||||
|
*
|
||||||
|
* @param currentUserCount The new user count for this Connection.
|
||||||
|
*/
|
||||||
|
public void setCurrentUserCount(int currentUserCount) {
|
||||||
|
this.currentUserCount = currentUserCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Connection for the given connectionID with a zero
|
||||||
|
* current user count.
|
||||||
|
*
|
||||||
|
* @param connectionID The ID of the MySQL connection that this
|
||||||
|
* Connection represents.
|
||||||
|
*/
|
||||||
|
public Connection(int connectionID) {
|
||||||
|
this.connectionID = connectionID;
|
||||||
|
this.currentUserCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Connection other) {
|
||||||
|
// Sort only based on current user count
|
||||||
|
return this.currentUserCount - other.currentUserCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DAO for accessing connection history.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of all the connections that are currently active the
|
||||||
|
* count of current users.
|
||||||
|
*/
|
||||||
|
private Map<Integer, Connection> activeConnectionMap =
|
||||||
|
new HashMap<Integer, Connection>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of the connection with the lowest number of current
|
||||||
|
* active users, if found.
|
||||||
|
*
|
||||||
|
* @param connectionIDs
|
||||||
|
*
|
||||||
|
* @return The ID of the connection with the lowest number of current
|
||||||
|
* active users, if found.
|
||||||
|
*/
|
||||||
|
public Integer getLeastUsedConnection(Collection<Integer> connectionIDs) {
|
||||||
|
|
||||||
|
if(connectionIDs.isEmpty())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<Connection> groupConnections =
|
||||||
|
new ArrayList<ActiveConnectionMap.Connection>();
|
||||||
|
|
||||||
|
for(Integer connectionID : connectionIDs) {
|
||||||
|
Connection connection = activeConnectionMap.get(connectionID);
|
||||||
|
|
||||||
|
// Create the Connection if it does not exist
|
||||||
|
if(connection == null) {
|
||||||
|
connection = new Connection(connectionID);
|
||||||
|
activeConnectionMap.put(connectionID, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupConnections.add(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the Connections into decending order
|
||||||
|
Collections.sort(groupConnections);
|
||||||
|
|
||||||
|
if(!groupConnections.isEmpty())
|
||||||
|
return groupConnections.get(0).getConnectionID();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the count of currently active users for the given connectionID.
|
||||||
|
* @return the count of currently active users for the given connectionID.
|
||||||
|
*/
|
||||||
|
public int getCurrentUserCount(int connectionID) {
|
||||||
|
Connection connection = activeConnectionMap.get(connectionID);
|
||||||
|
|
||||||
|
if(connection == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return connection.getCurrentUserCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the current user count for this Connection.
|
||||||
|
*
|
||||||
|
* @param connectionID The ID of the MySQL connection that this
|
||||||
|
* Connection represents.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException If the connection is not found.
|
||||||
|
*/
|
||||||
|
private void decrementUserCount(int connectionID)
|
||||||
|
throws GuacamoleException {
|
||||||
|
Connection connection = activeConnectionMap.get(connectionID);
|
||||||
|
|
||||||
|
if(connection == null)
|
||||||
|
throw new GuacamoleException
|
||||||
|
("Connection to decrement does not exist.");
|
||||||
|
|
||||||
|
// Decrement the current user count
|
||||||
|
connection.setCurrentUserCount(connection.getCurrentUserCount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the current user count for this Connection.
|
||||||
|
*
|
||||||
|
* @param connectionID The ID of the MySQL connection that this
|
||||||
|
* Connection represents.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException If the connection is not found.
|
||||||
|
*/
|
||||||
|
private void incrementUserCount(int connectionID) {
|
||||||
|
Connection connection = activeConnectionMap.get(connectionID);
|
||||||
|
|
||||||
|
// If the Connection does not exist, it should be created
|
||||||
|
if(connection == null) {
|
||||||
|
connection = new Connection(connectionID);
|
||||||
|
activeConnectionMap.put(connectionID, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the current user count
|
||||||
|
connection.setCurrentUserCount(connection.getCurrentUserCount() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a connection is currently in use.
|
||||||
|
* @param connectionID The connection to check the status of.
|
||||||
|
* @return true if the connection is currently in use.
|
||||||
|
*/
|
||||||
|
public boolean isActive(int connectionID) {
|
||||||
|
return getCurrentUserCount(connectionID) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a connection as open.
|
||||||
|
* @param connectionID The ID of the connection that is being opened.
|
||||||
|
* @param userID The ID of the user who is opening the connection.
|
||||||
|
* @return The ID of the history record created for this open connection.
|
||||||
|
*/
|
||||||
|
public int openConnection(int connectionID, int userID) {
|
||||||
|
|
||||||
|
// Create the connection history record
|
||||||
|
ConnectionHistory connectionHistory = new ConnectionHistory();
|
||||||
|
connectionHistory.setConnection_id(connectionID);
|
||||||
|
connectionHistory.setUser_id(userID);
|
||||||
|
connectionHistory.setStart_date(new Date());
|
||||||
|
connectionHistoryDAO.insert(connectionHistory);
|
||||||
|
|
||||||
|
// Increment the user count
|
||||||
|
incrementUserCount(connectionID);
|
||||||
|
|
||||||
|
return connectionHistory.getHistory_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a connection as closed.
|
||||||
|
* @param connectionID The ID of the connection that is being opened.
|
||||||
|
* @param historyID The ID of the history record about the open connection.
|
||||||
|
* @throws GuacamoleException If the open connection history is not found.
|
||||||
|
*/
|
||||||
|
public void closeConnection(int connectionID, int historyID)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Get the existing history record
|
||||||
|
ConnectionHistory connectionHistory =
|
||||||
|
connectionHistoryDAO.selectByPrimaryKey(historyID);
|
||||||
|
|
||||||
|
if(connectionHistory == null)
|
||||||
|
throw new GuacamoleException("History record not found.");
|
||||||
|
|
||||||
|
// Update the connection history record to mark that it is now closed
|
||||||
|
connectionHistory.setEnd_date(new Date());
|
||||||
|
connectionHistoryDAO.updateByPrimaryKey(connectionHistory);
|
||||||
|
|
||||||
|
// Decrement the user count.
|
||||||
|
decrementUserCount(connectionID);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,121 +0,0 @@
|
|||||||
|
|
||||||
package net.sourceforge.guacamole.net.auth.mysql;
|
|
||||||
|
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (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.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is guacamole-auth-mysql.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* James Muehlner.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import net.sourceforge.guacamole.GuacamoleException;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the set of currently active Connections. Whenever a socket is
|
|
||||||
* opened, the connection ID should be added to this set, and whenever a socket
|
|
||||||
* is closed, the connection ID should be removed from this set.
|
|
||||||
*
|
|
||||||
* @author James Muehlner
|
|
||||||
*/
|
|
||||||
public class ActiveConnectionSet {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DAO for accessing connection history.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set of all the connections that are currently active.
|
|
||||||
*/
|
|
||||||
private Set<Integer> activeConnectionSet = new HashSet<Integer>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a connection is currently in use.
|
|
||||||
* @param connectionID The connection to check the status of.
|
|
||||||
* @return true if the connection is currently in use.
|
|
||||||
*/
|
|
||||||
public boolean isActive(int connectionID) {
|
|
||||||
return activeConnectionSet.contains(connectionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a connection as open.
|
|
||||||
* @param connectionID The ID of the connection that is being opened.
|
|
||||||
* @param userID The ID of the user who is opening the connection.
|
|
||||||
* @return The ID of the history record created for this open connection.
|
|
||||||
*/
|
|
||||||
public int openConnection(int connectionID, int userID) {
|
|
||||||
|
|
||||||
// Create the connection history record
|
|
||||||
ConnectionHistory connectionHistory = new ConnectionHistory();
|
|
||||||
connectionHistory.setConnection_id(connectionID);
|
|
||||||
connectionHistory.setUser_id(userID);
|
|
||||||
connectionHistory.setStart_date(new Date());
|
|
||||||
connectionHistoryDAO.insert(connectionHistory);
|
|
||||||
|
|
||||||
// Mark the connection as active
|
|
||||||
activeConnectionSet.add(connectionID);
|
|
||||||
|
|
||||||
return connectionHistory.getHistory_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a connection as closed.
|
|
||||||
* @param connectionID The ID of the connection that is being opened.
|
|
||||||
* @param historyID The ID of the history record about the open connection.
|
|
||||||
* @throws GuacamoleException If the open connection history is not found.
|
|
||||||
*/
|
|
||||||
public void closeConnection(int connectionID, int historyID)
|
|
||||||
throws GuacamoleException {
|
|
||||||
|
|
||||||
// Get the existing history record
|
|
||||||
ConnectionHistory connectionHistory =
|
|
||||||
connectionHistoryDAO.selectByPrimaryKey(historyID);
|
|
||||||
|
|
||||||
if(connectionHistory == null)
|
|
||||||
throw new GuacamoleException("History record not found.");
|
|
||||||
|
|
||||||
// Update the connection history record to mark that it is now closed
|
|
||||||
connectionHistory.setEnd_date(new Date());
|
|
||||||
connectionHistoryDAO.updateByPrimaryKey(connectionHistory);
|
|
||||||
|
|
||||||
// Remove the connection from the set of active connections.
|
|
||||||
activeConnectionSet.remove(connectionID);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -81,7 +81,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
|||||||
/**
|
/**
|
||||||
* Set of all active connections.
|
* Set of all active connections.
|
||||||
*/
|
*/
|
||||||
private ActiveConnectionSet activeConnectionSet = new ActiveConnectionSet();
|
private ActiveConnectionMap activeConnectionSet = new ActiveConnectionMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injector which will manage the object graph of this authentication
|
* Injector which will manage the object graph of this authentication
|
||||||
@@ -175,7 +175,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
|||||||
bind(ConnectionService.class);
|
bind(ConnectionService.class);
|
||||||
bind(ConnectionGroupService.class);
|
bind(ConnectionGroupService.class);
|
||||||
bind(UserService.class);
|
bind(UserService.class);
|
||||||
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
|
bind(ActiveConnectionMap.class).toInstance(activeConnectionSet);
|
||||||
|
|
||||||
}
|
}
|
||||||
} // end of mybatis module
|
} // end of mybatis module
|
||||||
|
@@ -50,10 +50,10 @@ import net.sourceforge.guacamole.net.GuacamoleSocket;
|
|||||||
public class MySQLGuacamoleSocket implements GuacamoleSocket {
|
public class MySQLGuacamoleSocket implements GuacamoleSocket {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injected ActiveConnectionSet which will contain all active connections.
|
* Injected ActiveConnectionMap which will contain all active connections.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private ActiveConnectionSet activeConnectionSet;
|
private ActiveConnectionMap activeConnectionSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wrapped socket.
|
* The wrapped socket.
|
||||||
|
@@ -37,24 +37,25 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import net.sourceforge.guacamole.GuacamoleClientException;
|
||||||
|
import net.sourceforge.guacamole.GuacamoleException;
|
||||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
|
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroup;
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroup;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample;
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample.Criteria;
|
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample.Criteria;
|
||||||
|
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||||
|
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||||
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +66,12 @@ import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
|||||||
*/
|
*/
|
||||||
public class ConnectionGroupService {
|
public class ConnectionGroupService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for managing connections.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ConnectionService connectionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO for accessing connection groups.
|
* DAO for accessing connection groups.
|
||||||
*/
|
*/
|
||||||
@@ -77,6 +84,11 @@ public class ConnectionGroupService {
|
|||||||
@Inject
|
@Inject
|
||||||
private Provider<MySQLConnectionGroup> mysqlConnectionGroupProvider;
|
private Provider<MySQLConnectionGroup> mysqlConnectionGroupProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The map of all active connections.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ActiveConnectionMap activeConnectionMap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,9 +169,45 @@ public class ConnectionGroupService {
|
|||||||
return toMySQLConnectionGroup(connectionGroup, userID);
|
return toMySQLConnectionGroup(connectionGroup, userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the connection within the given group with the lowest number
|
||||||
|
* of currently active users.
|
||||||
|
*
|
||||||
|
* @param connection The group to load balance across.
|
||||||
|
* @param info The information to use when performing the connection
|
||||||
|
* handshake.
|
||||||
|
* @param userID The ID of the user who is connecting to the socket.
|
||||||
|
* @return The connected socket.
|
||||||
|
* @throws GuacamoleException If an error occurs while connecting the
|
||||||
|
* socket.
|
||||||
|
*/
|
||||||
public GuacamoleSocket connect(MySQLConnectionGroup group,
|
public GuacamoleSocket connect(MySQLConnectionGroup group,
|
||||||
GuacamoleClientInformation info, int userID) {
|
GuacamoleClientInformation info, int userID) throws GuacamoleException {
|
||||||
throw new UnsupportedOperationException("Not yet implemented");
|
|
||||||
|
// Get all connections in the group.
|
||||||
|
List<Integer> connectionIDs = connectionService.getAllConnectionIDs
|
||||||
|
(group.getConnectionGroupID());
|
||||||
|
|
||||||
|
// Get the least used connection.
|
||||||
|
Integer leastUsedConnectionID =
|
||||||
|
activeConnectionMap.getLeastUsedConnection(connectionIDs);
|
||||||
|
|
||||||
|
if(leastUsedConnectionID == null)
|
||||||
|
throw new GuacamoleException("No connections found in group.");
|
||||||
|
|
||||||
|
if(GuacamoleProperties.getProperty(
|
||||||
|
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||||
|
&& activeConnectionMap.isActive(leastUsedConnectionID))
|
||||||
|
throw new GuacamoleClientException
|
||||||
|
("Cannot connect. All connections are in use.");
|
||||||
|
|
||||||
|
// Get the connection
|
||||||
|
MySQLConnection connection = connectionService
|
||||||
|
.retrieveConnection(leastUsedConnectionID, userID);
|
||||||
|
|
||||||
|
// Connect to the connection
|
||||||
|
return connectionService.connect(connection, info, userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -37,14 +37,10 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -54,7 +50,7 @@ import net.sourceforge.guacamole.GuacamoleException;
|
|||||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||||
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
|
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
|
||||||
import net.sourceforge.guacamole.net.SSLGuacamoleSocket;
|
import net.sourceforge.guacamole.net.SSLGuacamoleSocket;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionSet;
|
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
||||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
||||||
@@ -114,10 +110,10 @@ public class ConnectionService {
|
|||||||
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of all currently active connections.
|
* Map of all currently active connections.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private ActiveConnectionSet activeConnectionSet;
|
private ActiveConnectionMap activeConnectionMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service managing users.
|
* Service managing users.
|
||||||
@@ -340,7 +336,7 @@ public class ConnectionService {
|
|||||||
// connections are not allowed, disallow connection
|
// connections are not allowed, disallow connection
|
||||||
if(GuacamoleProperties.getProperty(
|
if(GuacamoleProperties.getProperty(
|
||||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||||
&& activeConnectionSet.isActive(connection.getConnectionID()))
|
&& activeConnectionMap.isActive(connection.getConnectionID()))
|
||||||
throw new GuacamoleClientException("Cannot connect. This connection is in use.");
|
throw new GuacamoleClientException("Cannot connect. This connection is in use.");
|
||||||
|
|
||||||
// Get guacd connection information
|
// Get guacd connection information
|
||||||
@@ -361,7 +357,7 @@ public class ConnectionService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Mark this connection as active
|
// Mark this connection as active
|
||||||
int historyID = activeConnectionSet.openConnection(connection.getConnectionID(), userID);
|
int historyID = activeConnectionMap.openConnection(connection.getConnectionID(), userID);
|
||||||
|
|
||||||
// Return new MySQLGuacamoleSocket
|
// Return new MySQLGuacamoleSocket
|
||||||
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
|
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
|
||||||
|
Reference in New Issue
Block a user