diff --git a/conf/core/cache.ccf b/conf/core/cache.ccf index 87d1338a5cf70da9b551744bc154190965d4bb46..672c798d126e9c759e0c7a59a81702733aa4e7b3 100644 --- a/conf/core/cache.ccf +++ b/conf/core/cache.ccf @@ -1,3 +1,35 @@ +# default caching options jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=1000 -jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache \ No newline at end of file +jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes + +# Caching of the backend transactions +jcs.region.BACKEND_UserRoles.cacheattributes.MaxObjects=100 +jcs.region.BACKEND_Users.cacheattributes.MaxObjects=100 +jcs.region.BACKEND_PermissionRules.cacheattributes.MaxObjects=1000 + +jcs.region.BACKEND_SparseEntities.cacheattributes.MaxObjects=1000 +jcs.region.BACKEND_EntityProperties.cacheattributes.MaxObjects=1000 +jcs.region.BACKEND_EntityParents.cacheattributes.MaxObjects=1000 +jcs.region.BACKEND_SparseFileRecordsByPath.cacheattributes.MaxObjects=1000 + +jcs.region.BACKEND_JobRules.cacheattributes.MaxObjects=100 + + +# PAM UserSource Caching: Cached Items expire after 60 seconds if they are not requested (idle) and after 600 seconds max. +# PAM_UnixUserGroups +jcs.region.PAM_UnixUserGroups.elementattributes.IsEternal=false +jcs.region.PAM_UnixUserGroups.elementattributes.MaxLife=600 +jcs.region.PAM_UnixUserGroups.elementattributes.IdleTime=60 + +# PAM_UnixUserExists +jcs.region.PAM_UnixUserExists.elementattributes.IsEternal=false +jcs.region.PAM_UnixUserExists.elementattributes.MaxLife=600 +jcs.region.PAM_UnixUserExists.elementattributes.IdleTime=60 + +# PAM_Authentication +jcs.region.PAM_Authentication.elementattributes.IsEternal=false +jcs.region.PAM_Authentication.elementattributes.MaxLife=600 +jcs.region.PAM_Authentication.elementattributes.IdleTime=60 + + diff --git a/conf/core/log4j2-default.properties b/conf/core/log4j2-default.properties index ab7aed268e1e1e1a4088796d68b9e065086b5958..b1697a73fe6703850865406e1441947614d00f47 100644 --- a/conf/core/log4j2-default.properties +++ b/conf/core/log4j2-default.properties @@ -12,6 +12,11 @@ appender.stderr.name = stderr appender.stderr.layout.type = PatternLayout appender.stderr.layout.pattern = [%d{yy-MMM-dd HH:mm:ss:SSS}] [%p] [%c{1}:%L] - %m%n appender.stderr.target = SYSTEM_ERR +appender.stderr.filter.threshold.type = ThresholdFilter +appender.stderr.filter.threshold.level = INFO +appender.stderr.filter.threshold.onMatch = ACCEPT +appender.stderr.filter.threshold.onMismatch = DENY + # ${LOG_DIR}/request_errors/...log appender.request_errors.type = RollingRandomAccessFile diff --git a/conf/core/server.conf b/conf/core/server.conf index 00b3b1a33dbab19f9931424cc91b5b11f9d137e3..882c4453f1dd2f11eb36bf6a534e0ba26b249c62 100644 --- a/conf/core/server.conf +++ b/conf/core/server.conf @@ -50,13 +50,6 @@ BUGTRACKER_URI= TRANSACTION_BENCHMARK_ENABLED=true CACHE_CONF_LOC=./conf/core/cache.ccf -RULES_CACHE_CAPACITY=100 -SPARSE_ENTITY_CACHE_CAPACITY=1000 -PROPERTIES_CACHE_CAPACITY=1000 -PARENTS_CACHE_CAPACITY=1000 -USER_ACCOUNT_CACHE_CAPACITY=100 -GROUP_CACHE_CAPACITY=100 - INSERT_FILES_IN_DIR_ALLOWED_DIRS= SUDO_PASSWORD= @@ -70,4 +63,4 @@ CERTIFICATES_KEY_PASSWORD= CERTIFICATES_KEY_STORE_PATH= CERTIFICATES_KEY_STORE_PASSWORD= -WEBUI_HTTP_HEADER_CACHE_MAX_AGE=28800 \ No newline at end of file +WEBUI_HTTP_HEADER_CACHE_MAX_AGE=28800 diff --git a/makefile b/makefile index 07d01edfd116d57cf46d1290df738626d3c5b769..53c822deac4faaa058d7b1a04329abf2eb03d0bb 100644 --- a/makefile +++ b/makefile @@ -4,6 +4,8 @@ # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2019 IndiScale GmbH +# Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -22,6 +24,7 @@ # SHELL:=/bin/bash +JPDA_PORT ?= 9000 compile: easy-units mvn compile @@ -33,7 +36,7 @@ run: compile mvn exec:java@run run-debug: jar - java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:9000,server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar + java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar run-single: java -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar diff --git a/src/main/java/caosdb/server/ServerProperties.java b/src/main/java/caosdb/server/ServerProperties.java index 929f845d8023dc9d81c62294a5318442fcfb52ea..e68016894d65a3b77e38aa2f84f48ece7db05683 100644 --- a/src/main/java/caosdb/server/ServerProperties.java +++ b/src/main/java/caosdb/server/ServerProperties.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -90,13 +92,6 @@ public class ServerProperties extends Properties { public static final String KEY_CACHE_CONF_LOC = "CACHE_CONF_LOC"; - public static final String KEY_RULES_CACHE_CAPACITY = "RULES_CACHE_CAPACITY"; - public static final String KEY_SPARSE_ENTITY_CACHE_CAPACITY = "SPARSE_ENTITY_CACHE_CAPACITY"; - public static final String KEY_PROPERTIES_CACHE_CAPACITY = "PROPERTIES_CACHE_CAPACITY"; - public static final String KEY_PARENTS_CACHE_CAPACITY = "PARENTS_CACHE_CAPACITY"; - public static final String KEY_USER_ACCOUNT_CACHE_CAPACITY = "USER_ACCOUNT_CACHE_CAPACITY"; - public static final String KEY_GROUP_CACHE_CAPACITY = "GROUP_CACHE_CAPACITY"; - public static final String KEY_TRANSACTION_BENCHMARK_ENABLED = "TRANSACTION_BENCHMARK_ENABLED"; public static final String KEY_INSERT_FILES_IN_DIR_ALLOWED_DIRS = diff --git a/src/main/java/caosdb/server/accessControl/Pam.java b/src/main/java/caosdb/server/accessControl/Pam.java index c222fb83dabe0e4ad4e99d096d33192bf65086a9..99f68faadc15c15d9404a504d15669f0c2604ea3 100644 --- a/src/main/java/caosdb/server/accessControl/Pam.java +++ b/src/main/java/caosdb/server/accessControl/Pam.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,23 +24,38 @@ */ package caosdb.server.accessControl; +import caosdb.server.caching.Cache; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; +import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.shiro.authz.AuthorizationException; import org.jvnet.libpam.PAMException; import org.jvnet.libpam.UnixUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +/** + * PAM UserSource for authenticating users via the Host's pam module. + * + * <p>A User's existence check and the retrieval of a user's groups is done by the org.jvnet.libpam + * library. + * + * <p>The authentication of a user via the password need root-access and is therefore done by a + * special shell script running with root privileges on the host. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ public class Pam implements UserSource { + private Logger logger = LogManager.getLogger(Pam.class); + public static class DefaultPamScriptCaller implements PamScriptCaller { - private Logger logger = LoggerFactory.getLogger(getClass()); + private Logger logger = LogManager.getLogger(Pam.class); private final String pam_script; @@ -64,7 +81,7 @@ public class Pam implements UserSource { try { pam_authentication = getProcess(username, password); - logger.info("call pam script"); + logger.trace("call pam script"); return pam_authentication.waitFor() == 0; } catch (final IOException e) { throw new RuntimeException(e); @@ -75,6 +92,11 @@ public class Pam implements UserSource { } public static final String DEFAULT_PAM_SCRIPT = "./misc/pam_authentication/pam_authentication.sh"; + + /* + * following constants are the names of the configuration parameters and parts of parameters in + * the user_sources.ini for the pam user source. + */ public static final String KEY_PAM_SCRIPT = "pam_script"; public static final String KEY_DEFAULT_USER_STATUS = "default_status"; public static final String KEY_GROUP = "group"; @@ -83,8 +105,9 @@ public class Pam implements UserSource { public static final String KEY_INCLUDE = "include"; public static final String KEY_ROLES = "roles"; public static final String SEPARATOR = "."; + public static final String KEY_EMAIL = "email"; public static final String REGEX_SPLIT_CSV = "\\s*,\\s*"; - private static final String KEY_EMAIL = "email"; + private String[] EXCLUDE_USERS = null; private String[] INCLUDE_USERS = null; private String[] EXCLUDE_GROUPS = null; @@ -92,16 +115,28 @@ public class Pam implements UserSource { private Map<String, String> map = null; private PamScriptCaller pamScriptCaller = null; + /* Caches for groups, user-existence and password validation */ + + private ICacheAccess<String, HashSet<String>> groupsCache = Cache.getCache("PAM_UnixUserGroups"); + private ICacheAccess<String, Boolean> userExistsCache = Cache.getCache("PAM_UnixUserExists"); + private ICacheAccess<String, Boolean> passwordValidCache = Cache.getCache("PAM_Authentication"); + @Override public void setMap(final Map<String, String> map) { this.map = map; this.pamScriptCaller = null; } - public Map<String, String> getMap() { + /** + * Return the current configuration of this user source. + * + * @return configuration. + */ + private Map<String, String> getMap() { return this.map; } + /** @see {@link UserSource#resolveRolesForUsername(String)} */ @Override public Set<String> resolveRolesForUsername(final String username) { final Set<String> resulting_roles = new HashSet<String>(); @@ -138,7 +173,40 @@ public class Pam implements UserSource { return resulting_roles; } - private static Set<String> getGroups(final String username) { + /** + * Get the UNIX groups of the user. + * + * <p>First, try to get them from the cache. Only ask the back-end if necessary and cache the + * results. + * + * @param username + * @return A user's UNIX groups. + */ + private Set<String> getGroups(final String username) { + Set<String> cached = groupsCache.get(username); + if (cached != null) { + return cached; + } + + Set<String> uncached = getGroupsNoCache(username); + if (uncached instanceof HashSet) { + groupsCache.put(username, (HashSet<String>) uncached); + } else { + groupsCache.put(username, new HashSet<String>(uncached)); + } + return uncached; + } + + /** + * Get the UNIX groups of the user directly from the back-end. + * + * <p>If the user does not exist, an empty set is returned. + * + * @param username + * @return A user's UNIX groups or an empty set. + */ + private Set<String> getGroupsNoCache(final String username) { + logger.trace("Retrieving UnixGroups", username); if (UnixUser.exists(username)) { try { return new UnixUser(username).getGroups(); @@ -146,7 +214,7 @@ public class Pam implements UserSource { throw new AuthorizationException(e); } } - return null; + return new HashSet<String>(); } @Override @@ -154,11 +222,38 @@ public class Pam implements UserSource { return "PAM"; } + /** + * Check if that user is known by the host's PAM. + * + * <p>Try the cache first. Only ask PAM directly if necessary and cache the results. + * + * @see {@link UserSource#isUserExisting(String)}. + * @return true iff the user is known. + */ @Override public boolean isUserExisting(final String username) { + Boolean cached = userExistsCache.get(username); + if (cached != null) { + return cached; + } + + boolean uncached = isUserExistingNoCache(username); + userExistsCache.put(username, uncached); + return uncached; + } + + /** + * Check if that user is known by the host's PAM (without caching). + * + * @param username + * @return true iff the user is known. + */ + private boolean isUserExistingNoCache(final String username) { + logger.trace("Check UnixUser.exists", username); return username != null && UnixUser.exists(username) && isIncorporated(username); } + /** @see {@link UserSource#isValid(String, String)}. */ @Override public boolean isValid(final String username, final String password) { if (isUserExisting(username)) { @@ -174,8 +269,40 @@ public class Pam implements UserSource { return this.pamScriptCaller; } + /** + * Check the validity of the password for that user by asking the pam script caller. + * + * <p>Try the cache first, only call the pam script if necessary and cache the results. + * + * @param caller + * @param username + * @param password + * @return true iff the password is correct. + */ private boolean isValid( final PamScriptCaller caller, final String username, final String password) { + String key = "<" + password + "::" + username + ">"; + Boolean cached = passwordValidCache.get(key); + if (cached != null) { + return cached; + } + + boolean uncached = isValidNoCache(caller, username, password); + passwordValidCache.put(key, uncached); + return uncached; + } + + /** + * Check the validity of the password for that user by asking the pam script caller. + * + * @param caller + * @param username + * @param password + * @return true iff the password is correct. + */ + private boolean isValidNoCache( + final PamScriptCaller caller, final String username, final String password) { + logger.trace("Check Password", username); return caller.isValid(username, password); } @@ -278,10 +405,15 @@ public class Pam implements UserSource { ret = n; } else if (ret != n) { // conflict -> ignore, go for pam-wide setting + ret = null; break; } } } + + if (ret != null) { + return ret; + } // by pam-wide setting if (this.map.containsKey(KEY_DEFAULT_USER_STATUS)) { return UserStatus.valueOf(this.map.get(KEY_DEFAULT_USER_STATUS).toUpperCase()); diff --git a/src/main/java/caosdb/server/accessControl/UserSource.java b/src/main/java/caosdb/server/accessControl/UserSource.java index 23ce7c45ce6cb9982ae5c7fac05a3a41037a5afe..0ece8d5014227916feb1c50b986aaf4d9a9bf91b 100644 --- a/src/main/java/caosdb/server/accessControl/UserSource.java +++ b/src/main/java/caosdb/server/accessControl/UserSource.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -25,19 +27,84 @@ package caosdb.server.accessControl; import java.util.Map; import java.util.Set; +/** + * UserSources are sources for users - i.e. they authenticate users and contain basic information + * about users. + * + * <p>UserSources let you + * <li>check if a user exists - {@link #isUserExisting(String)} + * <li>authenticate a user via a password - {@link #isValid(String, String)} + * <li>get the default {@link UserStatus} - {@link #getDefaultUserStatus(String)} + * <li>get the default email address - {@link #getDefaultUserEmail(String)} + * <li>retrieve a users roles - {@link #resolveRolesForUsername(String)} The default email and + * default {@link UserStatus} might be overridden by other settings in CaosDB - that's why they + * are called "default". + * + * <p>Also, the user's roles might be overridden by the internal user source {@link + * InternalUserSource}. + * + * <p>A UserSource is configured via {@link #setMap(Map)}. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ public interface UserSource { + /** + * Every UserSource has a unique name, e.g. PAM, CaosDB (which is default name of the internal + * user source {@link InternalUserSource}). + * + * @return name + */ public String getName(); + /** + * Check if a user exists. + * + * @param username + * @return true iff this user source knows a user with that name + */ public boolean isUserExisting(String username); + /** + * Return all roles that a user is associated with. + * + * @param username + * @return a user's roles + */ public Set<String> resolveRolesForUsername(final String username); + /** + * Configure this user source. The needed parameters are to be defined and documented by the + * implementations. + * + * @param map the configuration + */ public void setMap(Map<String, String> map); + /** + * Return the {@link UserStatus} of that user. + * + * @param username + * @return The user status of that user + */ public UserStatus getDefaultUserStatus(String username); + /** + * Return the email address of that user, or null if none is available as per this user source. + * + * <p>This method does not check if a user exists. So it will return null for unknown users. + * + * @param username + * @return The email address or null + */ public String getDefaultUserEmail(String username); + /** + * Check if the user can be authenticated by the given password. + * + * @param username + * @param password + * @return true iff the password was correct. + */ public boolean isValid(String username, String password); } diff --git a/src/main/java/caosdb/server/caching/Cache.java b/src/main/java/caosdb/server/caching/Cache.java new file mode 100644 index 0000000000000000000000000000000000000000..338b1d853fd0610be780362a0242193fa46eb320 --- /dev/null +++ b/src/main/java/caosdb/server/caching/Cache.java @@ -0,0 +1,50 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package caosdb.server.caching; + +import java.io.Serializable; +import org.apache.commons.jcs.access.behavior.ICacheAccess; + +/** + * Caching Helper Class used for all caches in the CaosDB Server. + * + * <p>The actual work is delegated to an instance of {@link JCSCacheHelper}. However, the delegate + * {@link #DELEGATE} can be be overridden for testing purposes with {@link #setDelegate(Cache)}. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ +public class Cache { + + /** The default cache helper delegate. */ + private static CacheHelper DELEGATE = new JCSCacheHelper(); + + public static void setDelegate(CacheHelper delegate) { + DELEGATE = delegate; + } + + public static final <K, V extends Serializable> ICacheAccess<K, V> getCache(String region) { + return DELEGATE.getCache(region); + } +} diff --git a/src/main/java/caosdb/server/caching/CacheHelper.java b/src/main/java/caosdb/server/caching/CacheHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..32c854400310959a7834fe32a6f90de9e1b584d1 --- /dev/null +++ b/src/main/java/caosdb/server/caching/CacheHelper.java @@ -0,0 +1,31 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package caosdb.server.caching; + +import java.io.Serializable; +import org.apache.commons.jcs.access.behavior.ICacheAccess; + +public interface CacheHelper { + + public <K, V extends Serializable> ICacheAccess<K, V> getCache(String region); +} diff --git a/src/main/java/caosdb/server/caching/JCSCacheHelper.java b/src/main/java/caosdb/server/caching/JCSCacheHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..dab2b77ceaab3d0caaf49d798a4819ca890b5e82 --- /dev/null +++ b/src/main/java/caosdb/server/caching/JCSCacheHelper.java @@ -0,0 +1,91 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package caosdb.server.caching; + +import caosdb.server.CaosDBServer; +import caosdb.server.ServerProperties; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.Properties; +import org.apache.commons.jcs.JCS; +import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * A CacheHelper implementation which is configured statically via the {@link + * ServerProperties#KEY_CACHE_CONF_LOC} properties file. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ +public class JCSCacheHelper implements CacheHelper { + + protected static Logger logger = LogManager.getLogger(JCSCacheHelper.class); + + // A No-Operation configuration for JCS + private static Properties getNOPCachingProperties() { + Properties ret = new Properties(); + ret.setProperty( + "jcs.default.cacheattributes", "org.apache.commons.jcs.engine.CompositeCacheAttributes"); + ret.setProperty("jcs.default.cacheattributes.MaxObjects", "0"); + return ret; + } + + // configure JCS + static { + Properties config = null; + try { + Properties p = new Properties(); + final InputStream is = + new FileInputStream(CaosDBServer.getServerProperty(ServerProperties.KEY_CACHE_CONF_LOC)); + p.load(is); + is.close(); + config = p; + } catch (final FileNotFoundException e) { + logger.error(e); + config = getNOPCachingProperties(); + } catch (final IOException e) { + logger.error(e); + config = getNOPCachingProperties(); + } + logger.info("Configuring JCS Caching with {}", config); + JCS.setConfigProperties(config); + } + + @Override + public <K, V extends Serializable> ICacheAccess<K, V> getCache(final String name) { + final ICacheAccess<K, V> cache = JCS.getInstance(name); + logger.info( + "Caching configuration for {}:\n+----{}\n+----{}", + name, + cache.getCacheAttributes(), + cache.getDefaultElementAttributes()); + + return cache; + } +} diff --git a/src/main/java/caosdb/server/database/CacheableBackendTransaction.java b/src/main/java/caosdb/server/database/CacheableBackendTransaction.java index 390a177fe899f89330aeb3d0959aab5bf1d52cbc..fc4c9659d9a8ea80393bebad945bd6badf9580c4 100644 --- a/src/main/java/caosdb/server/database/CacheableBackendTransaction.java +++ b/src/main/java/caosdb/server/database/CacheableBackendTransaction.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -24,14 +26,19 @@ package caosdb.server.database; import caosdb.server.database.exceptions.TransactionException; import java.io.Serializable; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public abstract class CacheableBackendTransaction<K, V extends Serializable> extends BackendTransaction { - public abstract V executeNoCache() throws TransactionException; - private Boolean cached = null; + private ICacheAccess<K, V> cache; + + public CacheableBackendTransaction(ICacheAccess<K, V> cache) { + this.cache = cache; + } + + public abstract V executeNoCache() throws TransactionException; @Override public final void execute() throws TransactionException { @@ -67,8 +74,8 @@ public abstract class CacheableBackendTransaction<K, V extends Serializable> protected abstract K getKey(); - protected CacheAccess<K, V> getCache() { - return null; + protected final ICacheAccess<K, V> getCache() { + return cache; } private final boolean cacheIsEnabled() { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java b/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java index 4bd6e5b9706fe743be6c924c3e1f86cb6ff83371..39deb1416c743f838bfc1b96c29fd845dbcef742 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java +++ b/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -41,6 +43,9 @@ public class DeleteSparseEntity extends BackendTransaction { @Override protected void execute() { RetrieveSparseEntity.removeCached(this.entity.getId()); + if (entity.hasFileProperties()) { + GetFileRecordByPath.removeCached(this.entity.getFileProperties().getPath()); + } final DeleteSparseEntityImpl ret = getImplementation(DeleteSparseEntityImpl.class); diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java b/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java index 195f16db5341fdcd204debbaad0217635d1fd222..8e0afcbdc50985f1fa1a939940c05f8429562c90 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java +++ b/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,20 +24,31 @@ */ package caosdb.server.database.backend.transaction; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; import caosdb.server.database.exceptions.TransactionException; import caosdb.server.database.proto.SparseEntity; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class GetFileRecordByPath extends CacheableBackendTransaction<String, SparseEntity> { + private static final ICacheAccess<String, SparseEntity> cache = + Cache.getCache("BACKEND_SparseFileRecordsByPath"); private final String path; private SparseEntity entity; public GetFileRecordByPath(final String path) { + super(cache); this.path = path; } + public static void removeCached(final String path) { + if (path != null && cache != null) { + cache.remove(path); + } + } + @Override protected String getKey() { return this.path; diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java index 5d1545d29b9bab295c9f335fe4eb083f12f748b2..5c1b0178f51496f83a4fac6a4ce3b2447abdccd5 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,26 +24,21 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.DatabaseUtils; import caosdb.server.database.backend.interfaces.RetrieveParentsImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.database.proto.VerySparseEntity; import caosdb.server.entity.EntityInterface; import java.util.ArrayList; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrieveParents extends CacheableBackendTransaction<Integer, ArrayList<VerySparseEntity>> { - private static final CacheAccess<Integer, ArrayList<VerySparseEntity>> cache = - Cache.getCache( - "ParentsCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_SPARSE_ENTITY_CACHE_CAPACITY))); + private static final ICacheAccess<Integer, ArrayList<VerySparseEntity>> cache = + Cache.getCache("BACKEND_EntityParents"); /** * To be called by DeleteEntityProperties on execution. @@ -54,14 +51,10 @@ public class RetrieveParents } } - @Override - protected CacheAccess<Integer, ArrayList<VerySparseEntity>> getCache() { - return cache; - } - private final EntityInterface entity; public RetrieveParents(final EntityInterface entity) { + super(cache); this.entity = entity; } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java b/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java index c0daecbc46ac90630eac83d0c7334d7da148d429..7e9925777c21a6d041759cfdade7682b85458566 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,28 +24,24 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.permissions.PermissionRule; import java.util.HashSet; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrievePermissionRules extends CacheableBackendTransaction<String, HashSet<PermissionRule>> { - private static final CacheAccess<String, HashSet<PermissionRule>> cache = - Cache.getCache( - "PermissionRulesCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_GROUP_CACHE_CAPACITY))); + private static final ICacheAccess<String, HashSet<PermissionRule>> cache = + Cache.getCache("BACKEND_PermissionRules"); private HashSet<PermissionRule> rules; private final String role; public RetrievePermissionRules(final String role) { + super(cache); this.role = role; } @@ -51,11 +49,6 @@ public class RetrievePermissionRules cache.remove(role); } - @Override - protected CacheAccess<String, HashSet<PermissionRule>> getCache() { - return cache; - } - @Override public HashSet<PermissionRule> executeNoCache() throws TransactionException { final RetrievePermissionRulesImpl t = getImplementation(RetrievePermissionRulesImpl.class); diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java index b75d91acba76a4d97b16395701afe42ff05c5fac..650cae3676ed2b6b50f86c76a5ce92b195290fc3 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,29 +24,24 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.DatabaseUtils; import caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.database.proto.ProtoProperty; import caosdb.server.entity.EntityInterface; import caosdb.server.entity.Role; import caosdb.server.entity.wrapper.Property; import java.util.ArrayList; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrieveProperties extends CacheableBackendTransaction<Integer, ArrayList<ProtoProperty>> { private final EntityInterface entity; - private static final CacheAccess<Integer, ArrayList<ProtoProperty>> cache = - Cache.getCache( - "PropertiesCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_PROPERTIES_CACHE_CAPACITY))); + private static final ICacheAccess<Integer, ArrayList<ProtoProperty>> cache = + Cache.getCache("BACKEND_EntityProperties"); /** * To be called by DeleteEntityProperties on execution. @@ -57,12 +54,8 @@ public class RetrieveProperties } } - @Override - protected CacheAccess<Integer, ArrayList<ProtoProperty>> getCache() { - return cache; - } - public RetrieveProperties(final EntityInterface entity) { + super(cache); this.entity = entity; } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java index e45879964ef8bafad0106238073ff8c9d87e2287..5bb6150a8640f45997a4a3432ad4ac27196cd15c 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,36 +24,26 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import caosdb.server.accessControl.Role; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrieveRole extends CacheableBackendTransaction<String, Role> { - private static final CacheAccess<String, Role> cache = - Cache.getCache( - "RolesCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_GROUP_CACHE_CAPACITY))); + private static final ICacheAccess<String, Role> cache = Cache.getCache("BACKEND_UserRoles"); private final String role_name; private Role role; - @Override - protected CacheAccess<String, Role> getCache() { - return cache; - } - public Role getRole() { return this.role; } public RetrieveRole(final String role) { + super(cache); this.role_name = role; } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java index df9f58671184fb70fca99ca7707f9270f75c87a1..a91b5021f1fa722a8e8831234fc8ebc2032ba115 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,30 +24,25 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.DatabaseUtils; import caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.database.proto.SparseEntity; import caosdb.server.entity.Entity; import caosdb.server.entity.EntityInterface; import caosdb.server.utils.EntityStatus; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrieveSparseEntity extends CacheableBackendTransaction<Integer, SparseEntity> { private final EntityInterface entity; - private static final CacheAccess<Integer, SparseEntity> cache = - Cache.getCache( - "SparseEntityCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_SPARSE_ENTITY_CACHE_CAPACITY))); + private static final ICacheAccess<Integer, SparseEntity> cache = + Cache.getCache("BACKEND_SparseEntities"); /** - * To be called by UpdateSparseEntity and DeleteEntity on execution. + * To be called by {@link UpdateSparseEntity} and {@link DeleteEntity} on execution. * * @param id */ @@ -55,17 +52,13 @@ public class RetrieveSparseEntity extends CacheableBackendTransaction<Integer, S } } - @Override - protected CacheAccess<Integer, SparseEntity> getCache() { - return cache; - } - public RetrieveSparseEntity(final EntityInterface entity) { + super(cache); this.entity = entity; } public RetrieveSparseEntity(final int id) { - this.entity = new Entity(id); + this(new Entity(id)); } @Override diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java index cb9cdd9e993b9399f2bec5c9bff7316e0754b9ed..72bc1e5b1ec3a3509cc5cbba23e38b908d4e969f 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -23,17 +25,15 @@ package caosdb.server.database.backend.transaction; import caosdb.datetime.UTCDateTime; -import caosdb.server.database.CacheableBackendTransaction; +import caosdb.server.database.BackendTransaction; import caosdb.server.database.backend.interfaces.RetrieveTransactionHistoryImpl; import caosdb.server.database.exceptions.TransactionException; import caosdb.server.database.proto.ProtoTransactionLogMessage; import caosdb.server.entity.EntityInterface; import caosdb.server.utils.TransactionLogMessage; import java.util.ArrayList; -import org.apache.commons.jcs.access.CacheAccess; -public class RetrieveTransactionHistory - extends CacheableBackendTransaction<Integer, ArrayList<ProtoTransactionLogMessage>> { +public class RetrieveTransactionHistory extends BackendTransaction { private final EntityInterface entity; @@ -42,25 +42,13 @@ public class RetrieveTransactionHistory } @Override - protected Integer getKey() { - return this.entity.getId(); - } - - @Override - protected CacheAccess<Integer, ArrayList<ProtoTransactionLogMessage>> getCache() { - return null; - } - - @Override - public ArrayList<ProtoTransactionLogMessage> executeNoCache() throws TransactionException { + protected void execute() { final RetrieveTransactionHistoryImpl t = getImplementation(RetrieveTransactionHistoryImpl.class); - return t.execute(getKey()); + process(t.execute(entity.getId())); } - @Override - protected void process(final ArrayList<ProtoTransactionLogMessage> l) - throws TransactionException { + private void process(final ArrayList<ProtoTransactionLogMessage> l) throws TransactionException { for (final ProtoTransactionLogMessage t : l) { final UTCDateTime dateTime = UTCDateTime.UTCSeconds(t.seconds, t.nanos); diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java index 7492df38adfcfd24d18f1a263be5070a8916c9c8..9f27152030f5c953ee7bd4ecfff8c83d3cbc8a73 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,43 +24,29 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import caosdb.server.accessControl.Principal; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.backend.interfaces.RetrieveUserImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.database.proto.ProtoUser; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RetrieveUser extends CacheableBackendTransaction<Principal, ProtoUser> { private ProtoUser user; - private static final CacheAccess<Principal, ProtoUser> cache = - Cache.getCache( - "UserAccountCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_USER_ACCOUNT_CACHE_CAPACITY))); + private static final ICacheAccess<Principal, ProtoUser> cache = Cache.getCache("BACKEND_Users"); private final Principal principal; - /** - * To be called by DeleteSparseEntity, SetPassword, and UpdateSparseEntity on execution. - * - * @param u - */ + /** To be called by DeleteSparseEntity, SetPassword, and UpdateSparseEntity on execution. */ public static void removeCached(final Principal principal) { if (principal != null && cache != null) { cache.remove(principal); } } - @Override - protected CacheAccess<Principal, ProtoUser> getCache() { - return cache; - } - public RetrieveUser(final Principal principal) { + super(cache); this.principal = principal; } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java b/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java index 1a8698ac1d698946e7a3e239c03e386bc200e2b6..303029b42179a697c939767e2caf4d490a803a69 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java +++ b/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,22 +24,22 @@ */ package caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; +import caosdb.server.caching.Cache; import caosdb.server.database.CacheableBackendTransaction; import caosdb.server.database.backend.interfaces.RuleLoaderImpl; import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.Cache; import caosdb.server.database.proto.Rule; import caosdb.server.entity.EntityInterface; import caosdb.server.entity.container.TransactionContainer; import caosdb.server.jobs.Job; import caosdb.server.transaction.Transaction; import java.util.ArrayList; -import org.apache.commons.jcs.access.CacheAccess; +import org.apache.commons.jcs.access.behavior.ICacheAccess; public class RuleLoader extends CacheableBackendTransaction<String, ArrayList<Rule>> { + private static final ICacheAccess<String, ArrayList<Rule>> cache = + Cache.getCache("BACKEND_JobRules"); private final Transaction<? extends TransactionContainer> transaction; private final EntityInterface e; private final Integer entity; @@ -49,6 +51,7 @@ public class RuleLoader extends CacheableBackendTransaction<String, ArrayList<Ru final Integer entity, final EntityInterface e, final Transaction<? extends TransactionContainer> transaction) { + super(cache); this.domain = domain; this.entity = entity; this.e = e; @@ -66,17 +69,6 @@ public class RuleLoader extends CacheableBackendTransaction<String, ArrayList<Ru + ">"; } - @Override - protected CacheAccess<String, ArrayList<Rule>> getCache() { - return rulesCache; - } - - private static CacheAccess<String, ArrayList<Rule>> rulesCache = - Cache.getCache( - "RulesCache", - Integer.valueOf( - CaosDBServer.getServerProperty(ServerProperties.KEY_RULES_CACHE_CAPACITY))); - public ArrayList<Job> getJobs() { return this.jobs; } diff --git a/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java b/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java index 57d22ef226e83caf7e3b37b48b53c1025afaa93f..c6a1c7683409e0c875484e14553e4aeac2757a71 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java +++ b/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -39,6 +41,9 @@ public class UpdateSparseEntity extends BackendTransaction { @Override public void execute() throws TransactionException { RetrieveSparseEntity.removeCached(this.entity.getId()); + if (entity.hasFileProperties()) { + GetFileRecordByPath.removeCached(this.entity.getFileProperties().getPath()); + } final UpdateSparseEntityImpl t = getImplementation(UpdateSparseEntityImpl.class); diff --git a/src/main/java/caosdb/server/database/misc/Cache.java b/src/main/java/caosdb/server/database/misc/Cache.java deleted file mode 100644 index 7f364d4ab3e2ddc2d3e5e0638be4fe5dfa252ccd..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/misc/Cache.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.misc; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.terminal.StatLabel; -import caosdb.server.terminal.StatsPanel; -import caosdb.server.utils.AbstractObservable; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.util.Properties; -import org.apache.commons.jcs.JCS; -import org.apache.commons.jcs.access.CacheAccess; - -public class Cache { - - static { - final Properties p = new Properties(); - try { - final InputStream is = - new FileInputStream(CaosDBServer.getServerProperty(ServerProperties.KEY_CACHE_CONF_LOC)); - p.load(is); - is.close(); - } catch (final FileNotFoundException e) { - e.printStackTrace(); - } catch (final IOException e) { - e.printStackTrace(); - } - JCS.setConfigProperties(p); - } - - public static <K, V extends Serializable> CacheAccess<K, V> getCache( - final String name, final int capacity) { - if (capacity > 0) { - final CacheAccess<K, V> cache = JCS.getInstance(name); - cache.getCacheAttributes().setMaxObjects(capacity); - StatsPanel.addStat( - name, - new AbstractObservable() { - @Override - public String toString() { - return cache.getStats(); - }; - }); - StatsPanel.addStat( - name, - new StatLabel( - "Configuration", cache.getCacheAttributes().toString().replaceAll(",", "\n"))); - - return cache; - } - return null; - } -}