mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-1253: Update select all queries to process in batches.
This commit is contained in:
committed by
Mike Jumper
parent
7e38a089cf
commit
2708a205d3
@@ -67,6 +67,19 @@ public abstract class JDBCEnvironment extends DelegatingEnvironment {
|
||||
*/
|
||||
public abstract int getAbsoluteMaxConnections() throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of identifiers/parameters to be
|
||||
* included in a single batch when executing SQL statements.
|
||||
*
|
||||
* @return
|
||||
* The maximum number of identifiers/parameters to be included
|
||||
* in a single batch.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the property.
|
||||
*/
|
||||
public abstract int getBatchSize() throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns the default maximum number of concurrent connections to allow to
|
||||
* any one connection, unless specified differently on an individual
|
||||
|
@@ -19,13 +19,18 @@
|
||||
|
||||
package org.apache.guacamole.auth.jdbc.base;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleSecurityException;
|
||||
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
|
||||
import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionMapper;
|
||||
import org.apache.guacamole.auth.jdbc.permission.ObjectPermissionModel;
|
||||
import org.apache.guacamole.auth.jdbc.user.UserModel;
|
||||
@@ -66,6 +71,12 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
|
||||
ObjectPermission.Type.ADMINISTER
|
||||
};
|
||||
|
||||
/**
|
||||
* The environment of the Guacamole server.
|
||||
*/
|
||||
@Inject
|
||||
private JDBCEnvironment environment;
|
||||
|
||||
/**
|
||||
* Returns an instance of a mapper for the type of object used by this
|
||||
* service.
|
||||
@@ -347,10 +358,10 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
|
||||
* A new collection containing only the strings within the provided
|
||||
* collection which are valid identifiers.
|
||||
*/
|
||||
protected Collection<String> filterIdentifiers(Collection<String> identifiers) {
|
||||
protected List<String> filterIdentifiers(Collection<String> identifiers) {
|
||||
|
||||
// Obtain enough space for a full copy of the given identifiers
|
||||
Collection<String> validIdentifiers = new ArrayList<String>(identifiers.size());
|
||||
List<String> validIdentifiers = new ArrayList<>(identifiers.size());
|
||||
|
||||
// Add only valid identifiers to the copy
|
||||
for (String identifier : identifiers) {
|
||||
@@ -387,26 +398,36 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
|
||||
Collection<String> identifiers) throws GuacamoleException {
|
||||
|
||||
// Ignore invalid identifiers
|
||||
identifiers = filterIdentifiers(identifiers);
|
||||
List<String> filteredIdentifiers = filterIdentifiers(identifiers);
|
||||
|
||||
// Do not query if no identifiers given
|
||||
if (identifiers.isEmpty())
|
||||
if (filteredIdentifiers.isEmpty())
|
||||
return Collections.<InternalType>emptyList();
|
||||
|
||||
Collection<ModelType> objects;
|
||||
int batchSize = environment.getBatchSize();
|
||||
|
||||
// Bypass permission checks if the user is privileged
|
||||
if (user.isPrivileged())
|
||||
objects = getObjectMapper().select(identifiers);
|
||||
boolean userIsPrivileged = user.isPrivileged();
|
||||
|
||||
// Process the filteredIdentifiers in batches using Lists.partition() and flatMap
|
||||
Collection<ModelType> allObjects = Lists.partition(filteredIdentifiers, batchSize).stream()
|
||||
.flatMap(chunk -> {
|
||||
Collection<ModelType> objects;
|
||||
|
||||
// Bypass permission checks if the user is privileged
|
||||
if (userIsPrivileged)
|
||||
objects = getObjectMapper().select(chunk);
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
objects = getObjectMapper().selectReadable(user.getUser().getModel(),
|
||||
chunk, user.getEffectiveUserGroups());
|
||||
|
||||
return objects.stream();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
objects = getObjectMapper().selectReadable(user.getUser().getModel(),
|
||||
identifiers, user.getEffectiveUserGroups());
|
||||
|
||||
// Return collection of requested objects
|
||||
return getObjectInstances(user, objects);
|
||||
|
||||
return getObjectInstances(user, allObjects);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -104,6 +104,20 @@ public class MySQLEnvironment extends JDBCEnvironment {
|
||||
* The default SSL mode for connecting to MySQL servers.
|
||||
*/
|
||||
private final MySQLSSLMode DEFAULT_SSL_MODE = MySQLSSLMode.PREFERRED;
|
||||
|
||||
/**
|
||||
* The default maximum number of identifiers/parameters to be included in a
|
||||
* single batch when executing SQL statements for MySQL and MariaDB.
|
||||
*
|
||||
* MySQL and MariaDB impose a limit on the maximum size of a query,
|
||||
* determined by the max_allowed_packet configuration variable. A value of
|
||||
* 1000 is chosen to accommodate the max_allowed_packet limit without
|
||||
* exceeding it.
|
||||
*
|
||||
* @see https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_allowed_packet
|
||||
* @see https://mariadb.com/kb/en/server-system-variables/#max_allowed_packet
|
||||
*/
|
||||
private static final int DEFAULT_BATCH_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* Constructs a new MySQLEnvironment, providing access to MySQL-specific
|
||||
@@ -134,6 +148,13 @@ public class MySQLEnvironment extends JDBCEnvironment {
|
||||
DEFAULT_ABSOLUTE_MAX_CONNECTIONS
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() throws GuacamoleException {
|
||||
return getProperty(MySQLGuacamoleProperties.MYSQL_BATCH_SIZE,
|
||||
DEFAULT_BATCH_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultMaxConnections() throws GuacamoleException {
|
||||
|
@@ -265,4 +265,16 @@ public class MySQLGuacamoleProperties {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum number of identifiers/parameters to be included in a single batch when
|
||||
* executing SQL statements.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty MYSQL_BATCH_SIZE =
|
||||
new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-batch-size"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -115,6 +115,18 @@ public class PostgreSQLEnvironment extends JDBCEnvironment {
|
||||
* The default value to use for SSL mode if none is explicitly configured.
|
||||
*/
|
||||
private final PostgreSQLSSLMode DEFAULT_SSL_MODE = PostgreSQLSSLMode.PREFER;
|
||||
|
||||
/**
|
||||
* The default maximum number of identifiers/parameters to be included in a
|
||||
* single batch when executing SQL statements for PostgreSQL.
|
||||
*
|
||||
* PostgreSQL has a maximum limit of 65535 parameters per prepared statement.
|
||||
* A value of 5000 is chosen to avoid potential performance issues or query
|
||||
* execution errors while staying well below the maximum limit.
|
||||
*
|
||||
* @see https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-PREPARED-STATEMENT-ARGS
|
||||
*/
|
||||
private static final int DEFAULT_BATCH_SIZE = 5000;
|
||||
|
||||
/**
|
||||
* Constructs a new PostgreSQLEnvironment, providing access to PostgreSQL-specific
|
||||
@@ -146,6 +158,13 @@ public class PostgreSQLEnvironment extends JDBCEnvironment {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() throws GuacamoleException {
|
||||
return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_BATCH_SIZE,
|
||||
DEFAULT_BATCH_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultMaxConnections() throws GuacamoleException {
|
||||
return getProperty(
|
||||
|
@@ -277,4 +277,16 @@ public class PostgreSQLGuacamoleProperties {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum number of identifiers/parameters to be included in a single batch when
|
||||
* executing SQL statements.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty POSTGRESQL_BATCH_SIZE =
|
||||
new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "postgresql-batch-size"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -88,6 +88,17 @@ public class SQLServerEnvironment extends JDBCEnvironment {
|
||||
*/
|
||||
public static final SQLServerDriver SQLSERVER_DEFAULT_DRIVER = SQLServerDriver.MICROSOFT_2005;
|
||||
|
||||
/**
|
||||
* The default maximum number of identifiers/parameters to be included in a
|
||||
* single batch when executing SQL statements for SQL Server.
|
||||
*
|
||||
* SQL Server supports a maximum of 2100 parameters per query. A value of
|
||||
* 1000 is chosen to stay within this limit and avoid query execution errors.
|
||||
*
|
||||
* @see https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server
|
||||
*/
|
||||
private static final int DEFAULT_BATCH_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* Constructs a new SQLServerEnvironment, providing access to SQLServer-specific
|
||||
* configuration options.
|
||||
@@ -117,6 +128,13 @@ public class SQLServerEnvironment extends JDBCEnvironment {
|
||||
DEFAULT_ABSOLUTE_MAX_CONNECTIONS
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() throws GuacamoleException {
|
||||
return getProperty(SQLServerGuacamoleProperties.SQLSERVER_BATCH_SIZE,
|
||||
DEFAULT_BATCH_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultMaxConnections() throws GuacamoleException {
|
||||
|
@@ -206,5 +206,17 @@ public class SQLServerGuacamoleProperties {
|
||||
public String getName() { return "sqlserver-auto-create-accounts"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum number of identifiers/parameters to be included in a single batch when
|
||||
* executing SQL statements.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty SQLSERVER_BATCH_SIZE =
|
||||
new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "sqlserver-batch-size"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user