From 914ca96a6b980b78449883779e100658d1df3585 Mon Sep 17 00:00:00 2001 From: alainbodiguel Date: Tue, 19 Dec 2023 13:59:52 +0100 Subject: [PATCH 1/2] Adding a LocalCacheFactory --- .../arlas/commons/cache/BaseCacheManager.java | 14 +- .../cache/BaseHazelcastCacheManager.java | 42 +-- .../commons/cache/BaseLocalCacheFactory.java | 36 ++ .../commons/cache/BaseLocalCacheManager.java | 67 ++++ .../commons/cache/NoBaseCacheFactory.java | 36 ++ ...heManager.java => NoBaseCacheManager.java} | 36 +- .../commons/utils/SelfExpiringHashMap.java | 323 ++++++++++++++++++ .../arlas/commons/utils/SelfExpiringMap.java | 75 ++++ .../io/arlas/filter/core/PolicyEnforcer.java | 2 + .../filter/impl/AbstractPolicyEnforcer.java | 34 +- .../arlas/filter/impl/HTTPPolicyEnforcer.java | 4 +- .../filter/impl/KeycloakPolicyEnforcer.java | 6 +- .../arlas/filter/impl/NoPolicyEnforcer.java | 5 + .../impl/cache/HazelcastCacheManager.java | 1 - .../core/impl/cache/LocalCacheFactory.java | 38 +++ .../core/impl/cache/LocalCacheManager.java | 86 +++++ .../core/impl}/cache/NoCacheFactory.java | 8 +- .../core/impl/cache/NoCacheManager.java | 86 +++++ .../java/io/arlas/server/app/ArlasServer.java | 1 + conf/configuration.yaml | 5 +- docker-compose.yml | 4 +- docs/arlas-server-configuration.md | 22 +- 22 files changed, 824 insertions(+), 107 deletions(-) create mode 100644 arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheFactory.java create mode 100644 arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java create mode 100644 arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheFactory.java rename arlas-commons/src/main/java/io/arlas/commons/cache/{NoCacheManager.java => NoBaseCacheManager.java} (59%) create mode 100644 arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringHashMap.java create mode 100644 arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringMap.java create mode 100644 arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java create mode 100644 arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java rename {arlas-commons/src/main/java/io/arlas/commons => arlas-core/src/main/java/io/arlas/server/core/impl}/cache/NoCacheFactory.java (83%) create mode 100644 arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheManager.java diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseCacheManager.java index e6f749a6d..1a1feb0cf 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseCacheManager.java +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseCacheManager.java @@ -22,19 +22,9 @@ public interface BaseCacheManager { Object getObject(String key, String ref); + void putObject(String key, String ref, Object col, long timeout); + void putObject(String key, String ref, Object col); void removeObject(String key, String ref); - - void putDecision(String p, Boolean decision); - - Boolean getDecision(String p); - - void removeDecision(String p); - - void putPermission(String token, String p); - - String getPermission(String token); - - void removePermission(String token); } diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java index f451c74ed..966e831d2 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java @@ -69,12 +69,13 @@ public Object getObject(String key, String ref) { init(); c = this.instance.getReplicatedMap(key).get(ref); } - LOGGER.debug("Returning object '" + ref + "' from cache (key=" + key + ") with value " + (c == null ? "null" : c.toString())); + LOGGER.debug(String.format("Returning {'%s':{'%s': '%s'}}", key, ref, (c == null ? "null" : c.toString()))); return c; } - private void putObject(String key, String ref, Object o, int timeout) { - LOGGER.debug("Inserting object '" + ref + "' with value '" + o.toString() + "' in cache (key=" + key +")"); + @Override + public void putObject(String key, String ref, Object o, long timeout) { + LOGGER.debug(String.format("Inserting {'%s':{'%s': '%s'}}", key, ref, o)); try { this.instance.getReplicatedMap(key).put(ref, o, timeout, TimeUnit.SECONDS); } catch (HazelcastInstanceNotActiveException e) { // recover from unexpected shutdown @@ -90,7 +91,7 @@ public void putObject(String key, String ref, Object o) { @Override public void removeObject(String key, String ref) { - LOGGER.debug("Clearing object '" + ref + "' from cache (key=" + key +")"); + LOGGER.debug(String.format("Clearing {'%s':{'%s': ''}}", key, ref)); try { this.instance.getReplicatedMap(key).remove(ref); } catch (HazelcastInstanceNotActiveException e) { // recover from unexpected shutdown @@ -98,37 +99,4 @@ public void removeObject(String key, String ref) { this.instance.getReplicatedMap(key).remove(ref); } } - - @Override - public void putDecision(String path, Boolean decision) { - // we don't want IAM decisions to be cached more than 1 minute - putObject("decisions", path, decision, cacheTimeout > 60 ? 60 : cacheTimeout); - } - - @Override - public Boolean getDecision(String path) { - return (Boolean) getObject("decisions", path); - } - - @Override - public void removeDecision(String path) { - removeObject("decisions", path); - } - - @Override - public void putPermission(String token, String rpt) { - // we don't want IAM permissions to be cached more than 1 minute - putObject("permissions", token, rpt, cacheTimeout > 60 ? 60 : cacheTimeout); - } - - @Override - public String getPermission(String token) { - return (String) getObject("permissions", token); - } - - @Override - public void removePermission(String token) { - removeObject("permissions", token); - } - } diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheFactory.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheFactory.java new file mode 100644 index 000000000..e71d4911b --- /dev/null +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.commons.cache; + +import io.arlas.commons.config.ArlasConfiguration; + +public class BaseLocalCacheFactory extends CacheFactory { + private final BaseCacheManager cacheManager; + + public BaseLocalCacheFactory(ArlasConfiguration configuration) { + super(configuration); + this.cacheManager = new BaseLocalCacheManager(configuration.arlasCacheTimeout); + } + + @Override + public BaseCacheManager getCacheManager() { + return this.cacheManager; + } +} diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java new file mode 100644 index 000000000..584faec9c --- /dev/null +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java @@ -0,0 +1,67 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.commons.cache; + +import io.arlas.commons.utils.SelfExpiringHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This cache holds a map (named 'collections') for storing the collection references + * and one map per collection (named '') for storing the elastic types. + * This is a local cache implementation (no network replication) + */ +public class BaseLocalCacheManager implements BaseCacheManager { + Logger LOGGER = LoggerFactory.getLogger(BaseLocalCacheManager.class); + final protected long cacheTimeout; + final protected Map> cache; + + public BaseLocalCacheManager(int cacheTimeout) { + this.cacheTimeout = cacheTimeout; + this.cache = new ConcurrentHashMap<>(); + } + + @Override + public Object getObject(String key, String ref) { + Object c = this.cache.computeIfAbsent(key, k -> new SelfExpiringHashMap<>()).get(ref); + LOGGER.debug(String.format("Returning {'%s':{'%s': '%s'}}", key, ref, (c == null ? "null" : c.toString()))); + return c; + } + + @Override + public void putObject(String key, String ref, Object o, long timeout) { + LOGGER.debug(String.format("Inserting {'%s':{'%s': '%s'}}", key, ref, o)); + this.cache.computeIfAbsent(key, k -> new SelfExpiringHashMap<>()).put(ref, o, timeout * 1000L); + } + + @Override + public void putObject(String key, String ref, Object o) { + putObject(key, ref, o, this.cacheTimeout); + } + + @Override + public void removeObject(String key, String ref) { + LOGGER.debug(String.format("Clearing {'%s':{'%s': ''}}", key, ref)); + this.cache.computeIfAbsent(key, k -> new SelfExpiringHashMap<>()).remove(ref); + } +} diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheFactory.java b/arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheFactory.java new file mode 100644 index 000000000..a73191e2f --- /dev/null +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheFactory.java @@ -0,0 +1,36 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.commons.cache; + +import io.arlas.commons.config.ArlasConfiguration; + +public class NoBaseCacheFactory extends CacheFactory { + private final BaseCacheManager cacheManager; + + public NoBaseCacheFactory(ArlasConfiguration configuration) { + super(configuration); + this.cacheManager = new NoBaseCacheManager(configuration.arlasCacheTimeout); + } + + @Override + public BaseCacheManager getCacheManager() { + return this.cacheManager; + } +} diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheManager.java similarity index 59% rename from arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheManager.java rename to arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheManager.java index bf490acf0..10dffb61f 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheManager.java +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/NoBaseCacheManager.java @@ -20,11 +20,10 @@ package io.arlas.commons.cache; /** - * This cache holds a replicated map (named 'collections') for storing the collection references - * and one replicated map per collection (named '') for storing the elastic types. + * This is a No Cache implementation (does nothing) */ -public class NoCacheManager implements BaseCacheManager { - public NoCacheManager(int cacheTimeout) { +public class NoBaseCacheManager implements BaseCacheManager { + public NoBaseCacheManager(int cacheTimeout) { } @Override @@ -33,37 +32,14 @@ public Object getObject(String key, String ref) { } @Override - public void putObject(String key, String ref, Object o) { - } - - @Override - public void removeObject(String key, String ref) { - } - - @Override - public void putDecision(String path, Boolean decision) { - } - - @Override - public Boolean getDecision(String path) { - return null; - } - - @Override - public void removeDecision(String path) { + public void putObject(String key, String ref, Object col, long timeout) { } @Override - public void putPermission(String token, String rpt) { - } - - @Override - public String getPermission(String token) { - return null; + public void putObject(String key, String ref, Object o) { } @Override - public void removePermission(String token) { + public void removeObject(String key, String ref) { } - } diff --git a/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringHashMap.java b/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringHashMap.java new file mode 100644 index 000000000..b7690a331 --- /dev/null +++ b/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringHashMap.java @@ -0,0 +1,323 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Copyright (c) 2018 Pierantonio Cangianiello + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.arlas.commons.utils; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; + +/** + * A HashMap which entries expires after the specified life time. + * The life-time can be defined on a per-key basis, or using a default one, that is passed to the + * constructor. + * + * @author Pierantonio Cangianiello + * @param the Key type + * @param the Value type + */ +public class SelfExpiringHashMap implements SelfExpiringMap { + + private final Map internalMap; + + private final Map> expiringKeys; + + /** + * Holds the map keys using the given life time for expiration. + */ + private final DelayQueue delayQueue = new DelayQueue(); + + /** + * The default max life time in milliseconds. + */ + private final long maxLifeTimeMillis; + + public SelfExpiringHashMap() { + internalMap = new ConcurrentHashMap(); + expiringKeys = new WeakHashMap>(); + this.maxLifeTimeMillis = Long.MAX_VALUE; + } + + public SelfExpiringHashMap(long defaultMaxLifeTimeMillis) { + internalMap = new ConcurrentHashMap(); + expiringKeys = new WeakHashMap>(); + this.maxLifeTimeMillis = defaultMaxLifeTimeMillis; + } + + public SelfExpiringHashMap(long defaultMaxLifeTimeMillis, int initialCapacity) { + internalMap = new ConcurrentHashMap(initialCapacity); + expiringKeys = new WeakHashMap>(initialCapacity); + this.maxLifeTimeMillis = defaultMaxLifeTimeMillis; + } + + public SelfExpiringHashMap(long defaultMaxLifeTimeMillis, int initialCapacity, float loadFactor) { + internalMap = new ConcurrentHashMap(initialCapacity, loadFactor); + expiringKeys = new WeakHashMap>(initialCapacity, loadFactor); + this.maxLifeTimeMillis = defaultMaxLifeTimeMillis; + } + + /** + * {@inheritDoc} + */ + @Override + public int size() { + cleanup(); + return internalMap.size(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEmpty() { + cleanup(); + return internalMap.isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsKey(Object key) { + cleanup(); + return internalMap.containsKey((K) key); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsValue(Object value) { + cleanup(); + return internalMap.containsValue((V) value); + } + + @Override + public V get(Object key) { + cleanup(); + renewKey((K) key); + return internalMap.get((K) key); + } + + /** + * {@inheritDoc} + */ + @Override + public V put(K key, V value) { + return this.put(key, value, maxLifeTimeMillis); + } + + /** + * {@inheritDoc} + */ + @Override + public V put(K key, V value, long lifeTimeMillis) { + cleanup(); + ExpiringKey delayedKey = new ExpiringKey(key, lifeTimeMillis); + ExpiringKey oldKey = expiringKeys.put((K) key, delayedKey); + if(oldKey != null) { + expireKey(oldKey); + expiringKeys.put((K) key, delayedKey); + } + delayQueue.offer(delayedKey); + return internalMap.put(key, value); + } + + /** + * {@inheritDoc} + */ + @Override + public V remove(Object key) { + V removedValue = internalMap.remove((K) key); + expireKey(expiringKeys.remove((K) key)); + return removedValue; + } + + /** + * Not supported. + */ + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean renewKey(K key) { + ExpiringKey delayedKey = expiringKeys.get((K) key); + if (delayedKey != null) { + delayedKey.renew(); + return true; + } + return false; + } + + private void expireKey(ExpiringKey delayedKey) { + if (delayedKey != null) { + delayedKey.expire(); + cleanup(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void clear() { + delayQueue.clear(); + expiringKeys.clear(); + internalMap.clear(); + } + + /** + * Not supported. + */ + @Override + public Set keySet() { + throw new UnsupportedOperationException(); + } + + /** + * Not supported. + */ + @Override + public Collection values() { + throw new UnsupportedOperationException(); + } + + /** + * Not supported. + */ + @Override + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + private void cleanup() { + ExpiringKey delayedKey = delayQueue.poll(); + while (delayedKey != null) { + internalMap.remove(delayedKey.getKey()); + expiringKeys.remove(delayedKey.getKey()); + delayedKey = delayQueue.poll(); + } + } + + private class ExpiringKey implements Delayed { + + private long startTime = System.currentTimeMillis(); + private final long maxLifeTimeMillis; + private final K key; + + public ExpiringKey(K key, long maxLifeTimeMillis) { + this.maxLifeTimeMillis = maxLifeTimeMillis; + this.key = key; + } + + public K getKey() { + return key; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ExpiringKey other = (ExpiringKey) obj; + if (this.key != other.key && (this.key == null || !this.key.equals(other.key))) { + return false; + } + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (this.key != null ? this.key.hashCode() : 0); + return hash; + } + + /** + * {@inheritDoc} + */ + @Override + public long getDelay(TimeUnit unit) { + return unit.convert(getDelayMillis(), TimeUnit.MILLISECONDS); + } + + private long getDelayMillis() { + return (startTime + maxLifeTimeMillis) - System.currentTimeMillis(); + } + + public void renew() { + startTime = System.currentTimeMillis(); + } + + public void expire() { + startTime = Long.MIN_VALUE; + } + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(Delayed that) { + return Long.compare(this.getDelayMillis(), ((ExpiringKey) that).getDelayMillis()); + } + } +} \ No newline at end of file diff --git a/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringMap.java b/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringMap.java new file mode 100644 index 000000000..a7aa71625 --- /dev/null +++ b/arlas-commons/src/main/java/io/arlas/commons/utils/SelfExpiringMap.java @@ -0,0 +1,75 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Copyright (c) 2018 Pierantonio Cangianiello + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.arlas.commons.utils; + +import java.util.Map; + +/** + * + * @author Pierantonio Cangianiello + * @param the Key type + * @param the Value type + */ +public interface SelfExpiringMap extends Map { + + /** + * Renews the specified key, setting the life time to the initial value. + * + * @param key + * @return true if the key is found, false otherwise + */ + public boolean renewKey(K key); + + /** + * Associates the given key to the given value in this map, with the specified life + * times in milliseconds. + * + * @param key + * @param value + * @param lifeTimeMillis + * @return a previously associated object for the given key (if exists). + */ + public V put(K key, V value, long lifeTimeMillis); + +} diff --git a/arlas-commons/src/main/java/io/arlas/filter/core/PolicyEnforcer.java b/arlas-commons/src/main/java/io/arlas/filter/core/PolicyEnforcer.java index dcde97957..5d630e5db 100644 --- a/arlas-commons/src/main/java/io/arlas/filter/core/PolicyEnforcer.java +++ b/arlas-commons/src/main/java/io/arlas/filter/core/PolicyEnforcer.java @@ -30,6 +30,8 @@ public interface PolicyEnforcer extends ContainerRequestFilter { PolicyEnforcer setAuthConf(ArlasAuthConfiguration conf) throws Exception; + PolicyEnforcer setCacheTimeout(long timeout) throws Exception; + PolicyEnforcer setCacheManager(BaseCacheManager cacheManager); default boolean isEnabled() { return true; } diff --git a/arlas-commons/src/main/java/io/arlas/filter/impl/AbstractPolicyEnforcer.java b/arlas-commons/src/main/java/io/arlas/filter/impl/AbstractPolicyEnforcer.java index ccc958c17..0d9d7773e 100644 --- a/arlas-commons/src/main/java/io/arlas/filter/impl/AbstractPolicyEnforcer.java +++ b/arlas-commons/src/main/java/io/arlas/filter/impl/AbstractPolicyEnforcer.java @@ -77,6 +77,7 @@ public abstract class AbstractPolicyEnforcer implements PolicyEnforcer { private final Logger LOGGER = LoggerFactory.getLogger(AbstractPolicyEnforcer.class); protected ArlasAuthConfiguration authConf; protected BaseCacheManager cacheManager; + private long cacheTimeout; protected boolean injectPermissions = true; private final Base64.Decoder decoder = Base64.getUrlDecoder(); @@ -93,6 +94,13 @@ public PolicyEnforcer setAuthConf(ArlasAuthConfiguration conf) throws Exception return this; } + @Override + public PolicyEnforcer setCacheTimeout(long timeout) throws Exception { + // max cache timeout is 60s for decisions + this.cacheTimeout = Math.min(timeout, 60); + return this; + } + @Override public PolicyEnforcer setCacheManager(BaseCacheManager baseCacheManager) { this.cacheManager = baseCacheManager; @@ -134,7 +142,7 @@ private void addTechnicalRolesToPermissions(Set permissions, Map TechnicalRoles.getTechnicalRolesPermissions().entrySet().stream() .filter(rolesPerm -> ((List) value).contains(rolesPerm.getKey())) - .filter(rolesPerm -> rolesPerm.getValue().get("permissions").size() > 0) + .filter(rolesPerm -> !rolesPerm.getValue().get("permissions").isEmpty()) .forEach(rolesPerm -> permissions.addAll(rolesPerm.getValue().get("permissions").stream() .map(rp -> ArlasClaims.replaceVar(rp, VAR_ORG, key)).toList()))); LOGGER.debug("Resulting permissions: " + permissions); @@ -216,7 +224,7 @@ public void filter(ContainerRequestContext ctx, String method, String path, Stri String.join(":", ARLAS_API_KEY, keyIdHeader, keySecretHeader) : authHeader.substring(7); try { - Boolean ok = cacheManager.getDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken)); + Boolean ok = getDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken)); if (ok != null && !ok) { logUAM(LOGGER::warn, DENIED,"forbidden (from cache): " + log); ctx.abortWith(Response.status(FORBIDDEN).build()); @@ -264,13 +272,13 @@ public void filter(ContainerRequestContext ctx, String method, String path, Stri ctx.setProperty("claims", arlasClaims.getRules()); if ((ok != null && ok) || arlasClaims.isAllowed(method, path)) { arlasClaims.injectHeaders(ctx.getHeaders(), transaction); - cacheManager.putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.TRUE); + putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.TRUE); logUAM(LOGGER::debug, ALLOWED, "granted: " + log); return; } } if (isPublic) { - cacheManager.putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.TRUE); + putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.TRUE); logUAM(LOGGER::debug, ALLOWED, "public (with token): " + log); return; } @@ -284,7 +292,7 @@ public void filter(ContainerRequestContext ctx, String method, String path, Stri } return; } - cacheManager.putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.FALSE); + putDecision(getDecisionCacheKey(ctx, method, fullPath, accessToken), Boolean.FALSE); logUAM(LOGGER::warn, DENIED,"forbidden (with token): " + log); ctx.abortWith(Response.status(FORBIDDEN).build()); } finally { @@ -292,6 +300,22 @@ public void filter(ContainerRequestContext ctx, String method, String path, Stri } } + protected void putPermission(String token, String rpt) { + cacheManager.putObject("permissions", token, rpt, this.cacheTimeout); + } + + protected String getPermission(String token) { + return (String) cacheManager.getObject("permissions", token); + } + + private Boolean getDecision(String path) { + return (Boolean) cacheManager.getObject("decisions", path); + } + + private void putDecision(String path, Boolean decision) { + cacheManager.putObject("decisions", path, decision, this.cacheTimeout); + } + private String getDecisionCacheKey(ContainerRequestContext ctx, String method, String uri, String accessToken) { return Integer.toString(Objects.hash( method, diff --git a/arlas-commons/src/main/java/io/arlas/filter/impl/HTTPPolicyEnforcer.java b/arlas-commons/src/main/java/io/arlas/filter/impl/HTTPPolicyEnforcer.java index 42bf4c68d..a629c670a 100644 --- a/arlas-commons/src/main/java/io/arlas/filter/impl/HTTPPolicyEnforcer.java +++ b/arlas-commons/src/main/java/io/arlas/filter/impl/HTTPPolicyEnforcer.java @@ -78,7 +78,7 @@ protected Map getRolesClaim(Object token, Optional org) protected Object getObjectToken(String accessToken, String orgFilter) throws Exception { boolean isApiKey = accessToken.startsWith(ARLAS_API_KEY); LOGGER.debug("accessToken=" + (isApiKey ? accessToken.split(":")[1] : decodeToken(accessToken))); - String token = cacheManager.getPermission(accessToken + orgFilter); + String token = getPermission(accessToken + orgFilter); if (token == null) { Invocation.Builder request = orgFilter == null ? resource.request() : resource.queryParam(ARLAS_ORG_FILTER, orgFilter).request(); if (isApiKey) { @@ -96,7 +96,7 @@ protected Object getObjectToken(String accessToken, String orgFilter) throws Exc } else { throw new ArlasException("Impossible to get permissions with given access token:" + accessToken); } - cacheManager.putPermission(accessToken + orgFilter, token); + putPermission(accessToken + orgFilter, token); } LOGGER.debug("RPT=" + decodeToken(token)); return JWT.decode(token); diff --git a/arlas-commons/src/main/java/io/arlas/filter/impl/KeycloakPolicyEnforcer.java b/arlas-commons/src/main/java/io/arlas/filter/impl/KeycloakPolicyEnforcer.java index 3d3c04886..2ada79ace 100644 --- a/arlas-commons/src/main/java/io/arlas/filter/impl/KeycloakPolicyEnforcer.java +++ b/arlas-commons/src/main/java/io/arlas/filter/impl/KeycloakPolicyEnforcer.java @@ -54,12 +54,12 @@ public PolicyEnforcer setAuthConf(ArlasAuthConfiguration conf) throws Exception @Override protected Object getObjectToken(String accessToken, String orgFilter) throws Exception { LOGGER.debug("accessToken=" + decodeToken(accessToken)); - String token = cacheManager.getPermission(accessToken); + String token = getPermission(accessToken); if (token == null) { token = authzClient.authorization(accessToken) .authorize(new AuthorizationRequest()) .getToken(); - cacheManager.putPermission(accessToken, token); + putPermission(accessToken, token); } LOGGER.debug("RPT=" + decodeToken(token)); return TokenVerifier.create(token, AccessToken.class).getToken(); @@ -78,7 +78,7 @@ protected Map getRolesClaim(Object token, Optional org) @Override protected Set getPermissionsClaim(Object token){ - return new HashSet(((AccessToken) token).getAuthorization().getPermissions().stream() + return new HashSet<>(((AccessToken) token).getAuthorization().getPermissions().stream() .map(Permission::getResourceName).toList()); } } diff --git a/arlas-commons/src/main/java/io/arlas/filter/impl/NoPolicyEnforcer.java b/arlas-commons/src/main/java/io/arlas/filter/impl/NoPolicyEnforcer.java index 797c5329b..b0085aff7 100644 --- a/arlas-commons/src/main/java/io/arlas/filter/impl/NoPolicyEnforcer.java +++ b/arlas-commons/src/main/java/io/arlas/filter/impl/NoPolicyEnforcer.java @@ -42,6 +42,11 @@ public PolicyEnforcer setAuthConf(ArlasAuthConfiguration conf) throws Exception return this; } + @Override + public PolicyEnforcer setCacheTimeout(long timeout) throws Exception { + return this; + } + @Override public PolicyEnforcer setCacheManager(BaseCacheManager cacheManager) { return this; diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java index 49c7e60a6..f66e21443 100644 --- a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java @@ -19,7 +19,6 @@ package io.arlas.server.core.impl.cache; -import co.elastic.clients.elasticsearch._types.mapping.Property; import io.arlas.commons.cache.BaseHazelcastCacheManager; import io.arlas.server.core.managers.CacheManager; import io.arlas.server.core.model.CollectionReference; diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java new file mode 100644 index 000000000..8ac44861c --- /dev/null +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java @@ -0,0 +1,38 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.server.core.impl.cache; + +import io.arlas.commons.cache.CacheFactory; +import io.arlas.commons.config.ArlasConfiguration; +import io.arlas.server.core.managers.CacheManager; + +public class LocalCacheFactory extends CacheFactory { + private final CacheManager cacheManager; + + public LocalCacheFactory(ArlasConfiguration configuration) { + super(configuration); + this.cacheManager = new LocalCacheManager(configuration.arlasCacheTimeout); + } + + @Override + public CacheManager getCacheManager() { + return this.cacheManager; + } +} diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java new file mode 100644 index 000000000..ea2559b09 --- /dev/null +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java @@ -0,0 +1,86 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.server.core.impl.cache; + +import io.arlas.commons.cache.BaseLocalCacheManager; +import io.arlas.commons.utils.SelfExpiringHashMap; +import io.arlas.server.core.managers.CacheManager; +import io.arlas.server.core.model.CollectionReference; +import io.arlas.server.core.model.response.FieldType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +/** + * This cache holds a map (named 'collections') for storing the collection references + * and one map per collection (named '') for storing the elastic types. + */ +public class LocalCacheManager extends BaseLocalCacheManager implements CacheManager { + Logger LOGGER = LoggerFactory.getLogger(LocalCacheManager.class); + + public LocalCacheManager(int cacheTimeout) { + super(cacheTimeout); + } + + @Override + public CollectionReference getCollectionReference(String ref) { + return (CollectionReference) getObject("collections", ref); + } + + @Override + public void putCollectionReference(String ref, CollectionReference col) { + putObject("collections", ref, col); + LOGGER.debug("Clearing field types of collection '" + ref + "' from cache"); + this.cache.computeIfAbsent(ref, k -> new SelfExpiringHashMap<>()).clear(); + } + + @Override + public void removeCollectionReference(String ref) { + removeObject("collections", ref); + LOGGER.debug("Clearing field types of collection '" + ref + "' from cache"); + this.cache.computeIfAbsent(ref, k -> new SelfExpiringHashMap<>()).clear(); + } + + @Override + public FieldType getFieldType(String ref, String name) { + return (FieldType) getObject(ref, name); + } + + @Override + public void putFieldType(String ref, String name, FieldType type) { + putObject(ref, name, type); + } + + @Override + public void putMapping(String indexName, Map> mapping) { + putObject("mappings", indexName, mapping); + } + + @Override + public Map> getMapping(String indexName) { + return (Map>) getObject("mappings", indexName); + } + + @Override + public void removeMapping(String indexName) { + removeObject("mappings", indexName); + } +} diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheFactory.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheFactory.java similarity index 83% rename from arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheFactory.java rename to arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheFactory.java index b1e991b5d..cb58090b8 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/NoCacheFactory.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheFactory.java @@ -17,12 +17,14 @@ * under the License. */ -package io.arlas.commons.cache; +package io.arlas.server.core.impl.cache; +import io.arlas.commons.cache.CacheFactory; import io.arlas.commons.config.ArlasConfiguration; +import io.arlas.server.core.managers.CacheManager; public class NoCacheFactory extends CacheFactory { - private final BaseCacheManager cacheManager; + private final CacheManager cacheManager; public NoCacheFactory(ArlasConfiguration configuration) { super(configuration); @@ -30,7 +32,7 @@ public NoCacheFactory(ArlasConfiguration configuration) { } @Override - public BaseCacheManager getCacheManager() { + public CacheManager getCacheManager() { return this.cacheManager; } } diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheManager.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheManager.java new file mode 100644 index 000000000..472c1aef1 --- /dev/null +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/NoCacheManager.java @@ -0,0 +1,86 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.arlas.server.core.impl.cache; + +import io.arlas.server.core.managers.CacheManager; +import io.arlas.server.core.model.CollectionReference; +import io.arlas.server.core.model.response.FieldType; + +import java.util.Map; + +/** + * This cache holds a replicated map (named 'collections') for storing the collection references + * and one replicated map per collection (named '') for storing the elastic types. + */ +public class NoCacheManager implements CacheManager { + public NoCacheManager(int cacheTimeout) {} + + @Override + public Object getObject(String key, String ref) { + return null; + } + + @Override + public void putObject(String key, String ref, Object col, long timeout) { + } + + @Override + public void putObject(String key, String ref, Object o) { + } + + @Override + public void removeObject(String key, String ref) { + } + + @Override + public CollectionReference getCollectionReference(String ref) { + return null; + } + + @Override + public void putCollectionReference(String ref, CollectionReference col) { + } + + @Override + public void removeCollectionReference(String ref) { + } + + @Override + public FieldType getFieldType(String ref, String name) { + return null; + } + + @Override + public void putFieldType(String ref, String name, FieldType type) { + } + + @Override + public void putMapping(String indexName, Map> exists) { + } + + @Override + public Map> getMapping(String indexName) { + return null; + } + + @Override + public void removeMapping(String indexName) { + } +} diff --git a/arlas-server/src/main/java/io/arlas/server/app/ArlasServer.java b/arlas-server/src/main/java/io/arlas/server/app/ArlasServer.java index a6c66327d..c73392112 100644 --- a/arlas-server/src/main/java/io/arlas/server/app/ArlasServer.java +++ b/arlas-server/src/main/java/io/arlas/server/app/ArlasServer.java @@ -166,6 +166,7 @@ public void run(ArlasServerConfiguration configuration, Environment environment) PolicyEnforcer policyEnforcer = PolicyEnforcer.newInstance(configuration.arlasAuthPolicyClass) .setAuthConf(configuration.arlasAuthConfiguration) + .setCacheTimeout(configuration.arlasCacheTimeout) .setCacheManager(cacheFactory.getCacheManager()); LOGGER.info("PolicyEnforcer: " + policyEnforcer.getClass().getCanonicalName()); environment.jersey().register(policyEnforcer); diff --git a/conf/configuration.yaml b/conf/configuration.yaml index 1b4173b79..f64124ae4 100644 --- a/conf/configuration.yaml +++ b/conf/configuration.yaml @@ -92,8 +92,9 @@ elastic: ############ CACHE ############### ######################################################## # Configuration of the cache -#arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.commons.cache.NoCacheFactory} -arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.HazelcastCacheFactory} +#arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.NoCacheFactory} +#arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.HazelcastCacheFactory} +arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.LocalCacheFactory} arlas-cache-size: ${ARLAS_CACHE_SIZE:-1000} arlas-cache-timeout: ${ARLAS_CACHE_TIMEOUT:-300} arlas-rest-cache-timeout: ${ARLAS_REST_CACHE_TIMEOUT:-0} diff --git a/docker-compose.yml b/docker-compose.yml index 95b37370d..c15e066e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,8 @@ services: image: gisaia/arlas-server:${ARLAS_VERSION:-latest} container_name: arlas-server environment: + - ARLAS_LOGGING_LEVEL="${ARLAS_LOGGING_LEVEL:-INFO}" + - ARLAS_LOGGING_CONSOLE_LEVEL="${ARLAS_LOGGING_CONSOLE_LEVEL:-INFO}" - ARLAS_ELASTIC_NODES=${ARLAS_ELASTIC_NODES:-elasticsearch:9200} - ARLAS_ELASTIC_ENABLE_SSL="${ARLAS_ELASTIC_ENABLE_SSL:-false}" - ARLAS_ELASTIC_IGNORE_CERTS="${ARLAS_ELASTIC_IGNORE_CERTS:-true}" @@ -24,7 +26,7 @@ services: - ARLAS_AUTH_PERMISSION_URL="${ARLAS_AUTH_PERMISSION_URL:-http://arlas-iam-server:9990/arlas_iam_server/permissions}" - ARLAS_CORS_ENABLED="${ARLAS_CORS_ENABLED:-false}" - ARLAS_AUTH_CERT_URL="${ARLAS_AUTH_CERT_URL}" - - ARLAS_CACHE_FACTORY_CLASS="${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.HazelcastCacheFactory}" + - ARLAS_CACHE_FACTORY_CLASS="${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.LocalCacheFactory}" - ARLAS_CACHE_TIMEOUT="${ARLAS_CACHE_TIMEOUT:-5}" - ARLAS_SWAGGER_RESOURCE_PKG="${ARLAS_SWAGGER_RESOURCE_PKG:-io.arlas.server.rest}" ports: diff --git a/docs/arlas-server-configuration.md b/docs/arlas-server-configuration.md index bfd173103..1937fd4eb 100644 --- a/docs/arlas-server-configuration.md +++ b/docs/arlas-server-configuration.md @@ -110,17 +110,17 @@ Refer to [ARLAS IAM configuration](arlas-iam.md) for a comprehensive configurati ### Collection Cache & Disovery -| Environment variable | ARLAS Server configuration variable | Default | Description | -|----------------------------------------|---------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------------------------------| -| ARLAS_CACHE_FACTORY_CLASS | Cache manager class | io.arlas.server.core.impl.cache.HazelcastCacheFactory | Class to be used for the cache manager | -| ARLAS_CACHE_SIZE | arlas-cache-size | 1000 | Size of the cache used for managing the collections | -| ARLAS_CACHE_TIMEOUT | arlas-cache-timeout | 60 | Number of seconds for the cache used for managing the collections | -| ARLAS_REST_CACHE_TIMEOUT | arlas-rest-cache-timeout | 0 | Number of seconds for the cache used for managing the REST responses | -| ARLAS_COLLECTION_AUTODISCOVER_SCHEDULE | collection-auto-discover.schedule | 0 | Number of seconds between two auto discovery tasks | -| N/A | collection-auto-discover.preferred-id-field-name | id,identifier | Name of the id field for auto discovery | -| N/A | collection-auto-discover.preferred-timestamp-field-name | params.startdate | Name of the timestamp field for auto discovery | -| N/A | collection-auto-discover.preferred-centroid-field-name | geo_params.centroid | Name of the centroid field for auto discovery | -| N/A | collection-auto-discover.preferred-geometry-field-name | geo,geo_params.geometry | Name of the geometry field for auto discovery | +| Environment variable | ARLAS Server configuration variable | Default | Description | +|----------------------------------------|---------------------------------------------------------|---------------------------------------------------|----------------------------------------------------------------------| +| ARLAS_CACHE_FACTORY_CLASS | Cache manager class | io.arlas.server.core.impl.cache.LocalCacheFactory | Class to be used for the cache manager | +| ARLAS_CACHE_SIZE | arlas-cache-size | 1000 | Size of the cache used for managing the collections | +| ARLAS_CACHE_TIMEOUT | arlas-cache-timeout | 60 | Number of seconds for the cache used for managing the collections | +| ARLAS_REST_CACHE_TIMEOUT | arlas-rest-cache-timeout | 0 | Number of seconds for the cache used for managing the REST responses | +| ARLAS_COLLECTION_AUTODISCOVER_SCHEDULE | collection-auto-discover.schedule | 0 | Number of seconds between two auto discovery tasks | +| N/A | collection-auto-discover.preferred-id-field-name | id,identifier | Name of the id field for auto discovery | +| N/A | collection-auto-discover.preferred-timestamp-field-name | params.startdate | Name of the timestamp field for auto discovery | +| N/A | collection-auto-discover.preferred-centroid-field-name | geo_params.centroid | Name of the centroid field for auto discovery | +| N/A | collection-auto-discover.preferred-geometry-field-name | geo,geo_params.geometry | Name of the geometry field for auto discovery | ### Server From 599ed114d2a6213439a9437d55c9c9978a127877 Mon Sep 17 00:00:00 2001 From: alainbodiguel Date: Mon, 15 Jan 2024 11:29:12 +0100 Subject: [PATCH 2/2] Renaming classes --- .../cache/BaseHazelcastCacheManager.java | 4 ---- .../commons/cache/BaseLocalCacheManager.java | 2 -- ...a => CollectionHazelcastCacheFactory.java} | 6 ++--- ...a => CollectionHazelcastCacheManager.java} | 6 ++--- ....java => CollectionLocalCacheFactory.java} | 6 ++--- ....java => CollectionLocalCacheManager.java} | 6 ++--- conf/configuration.yaml | 4 ++-- docker-compose.yml | 2 +- docs/arlas-server-configuration.md | 22 +++++++++---------- 9 files changed, 26 insertions(+), 32 deletions(-) rename arlas-core/src/main/java/io/arlas/server/core/impl/cache/{LocalCacheFactory.java => CollectionHazelcastCacheFactory.java} (82%) rename arlas-core/src/main/java/io/arlas/server/core/impl/cache/{HazelcastCacheManager.java => CollectionHazelcastCacheManager.java} (91%) rename arlas-core/src/main/java/io/arlas/server/core/impl/cache/{HazelcastCacheFactory.java => CollectionLocalCacheFactory.java} (83%) rename arlas-core/src/main/java/io/arlas/server/core/impl/cache/{LocalCacheManager.java => CollectionLocalCacheManager.java} (92%) diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java index 966e831d2..2e34d02f9 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseHazelcastCacheManager.java @@ -28,10 +28,6 @@ import java.util.concurrent.TimeUnit; -/** - * This cache holds a replicated map (named 'collections') for storing the collection references - * and one replicated map per collection (named '') for storing the elastic types. - */ public class BaseHazelcastCacheManager implements BaseCacheManager { Logger LOGGER = LoggerFactory.getLogger(BaseHazelcastCacheManager.class); final private Config hzConfig; diff --git a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java index 584faec9c..311d4508d 100644 --- a/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java +++ b/arlas-commons/src/main/java/io/arlas/commons/cache/BaseLocalCacheManager.java @@ -27,8 +27,6 @@ import java.util.concurrent.ConcurrentHashMap; /** - * This cache holds a map (named 'collections') for storing the collection references - * and one map per collection (named '') for storing the elastic types. * This is a local cache implementation (no network replication) */ public class BaseLocalCacheManager implements BaseCacheManager { diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheFactory.java similarity index 82% rename from arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java rename to arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheFactory.java index 8ac44861c..68fd430e7 100644 --- a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheFactory.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheFactory.java @@ -23,12 +23,12 @@ import io.arlas.commons.config.ArlasConfiguration; import io.arlas.server.core.managers.CacheManager; -public class LocalCacheFactory extends CacheFactory { +public class CollectionHazelcastCacheFactory extends CacheFactory { private final CacheManager cacheManager; - public LocalCacheFactory(ArlasConfiguration configuration) { + public CollectionHazelcastCacheFactory(ArlasConfiguration configuration) { super(configuration); - this.cacheManager = new LocalCacheManager(configuration.arlasCacheTimeout); + this.cacheManager = new CollectionHazelcastCacheManager(configuration.arlasCacheTimeout); } @Override diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheManager.java similarity index 91% rename from arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java rename to arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheManager.java index f66e21443..932b03fe1 100644 --- a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheManager.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionHazelcastCacheManager.java @@ -32,10 +32,10 @@ * This cache holds a replicated map (named 'collections') for storing the collection references * and one replicated map per collection (named '') for storing the elastic types. */ -public class HazelcastCacheManager extends BaseHazelcastCacheManager implements CacheManager { - Logger LOGGER = LoggerFactory.getLogger(HazelcastCacheManager.class); +public class CollectionHazelcastCacheManager extends BaseHazelcastCacheManager implements CacheManager { + Logger LOGGER = LoggerFactory.getLogger(CollectionHazelcastCacheManager.class); - public HazelcastCacheManager(int cacheTimeout) { + public CollectionHazelcastCacheManager(int cacheTimeout) { super(cacheTimeout); } diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheFactory.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheFactory.java similarity index 83% rename from arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheFactory.java rename to arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheFactory.java index 637470a6f..d6466de77 100644 --- a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/HazelcastCacheFactory.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheFactory.java @@ -23,12 +23,12 @@ import io.arlas.commons.config.ArlasConfiguration; import io.arlas.server.core.managers.CacheManager; -public class HazelcastCacheFactory extends CacheFactory { +public class CollectionLocalCacheFactory extends CacheFactory { private final CacheManager cacheManager; - public HazelcastCacheFactory(ArlasConfiguration configuration) { + public CollectionLocalCacheFactory(ArlasConfiguration configuration) { super(configuration); - this.cacheManager = new HazelcastCacheManager(configuration.arlasCacheTimeout); + this.cacheManager = new CollectionLocalCacheManager(configuration.arlasCacheTimeout); } @Override diff --git a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheManager.java similarity index 92% rename from arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java rename to arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheManager.java index ea2559b09..c88730524 100644 --- a/arlas-core/src/main/java/io/arlas/server/core/impl/cache/LocalCacheManager.java +++ b/arlas-core/src/main/java/io/arlas/server/core/impl/cache/CollectionLocalCacheManager.java @@ -33,10 +33,10 @@ * This cache holds a map (named 'collections') for storing the collection references * and one map per collection (named '') for storing the elastic types. */ -public class LocalCacheManager extends BaseLocalCacheManager implements CacheManager { - Logger LOGGER = LoggerFactory.getLogger(LocalCacheManager.class); +public class CollectionLocalCacheManager extends BaseLocalCacheManager implements CacheManager { + Logger LOGGER = LoggerFactory.getLogger(CollectionLocalCacheManager.class); - public LocalCacheManager(int cacheTimeout) { + public CollectionLocalCacheManager(int cacheTimeout) { super(cacheTimeout); } diff --git a/conf/configuration.yaml b/conf/configuration.yaml index f64124ae4..49818d98b 100644 --- a/conf/configuration.yaml +++ b/conf/configuration.yaml @@ -93,8 +93,8 @@ elastic: ######################################################## # Configuration of the cache #arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.NoCacheFactory} -#arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.HazelcastCacheFactory} -arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.LocalCacheFactory} +#arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.CollectionHazelcastCacheFactory} +arlas_cache_factory_class: ${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.CollectionLocalCacheFactory} arlas-cache-size: ${ARLAS_CACHE_SIZE:-1000} arlas-cache-timeout: ${ARLAS_CACHE_TIMEOUT:-300} arlas-rest-cache-timeout: ${ARLAS_REST_CACHE_TIMEOUT:-0} diff --git a/docker-compose.yml b/docker-compose.yml index c15e066e2..6a6dbc74f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ services: - ARLAS_AUTH_PERMISSION_URL="${ARLAS_AUTH_PERMISSION_URL:-http://arlas-iam-server:9990/arlas_iam_server/permissions}" - ARLAS_CORS_ENABLED="${ARLAS_CORS_ENABLED:-false}" - ARLAS_AUTH_CERT_URL="${ARLAS_AUTH_CERT_URL}" - - ARLAS_CACHE_FACTORY_CLASS="${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.LocalCacheFactory}" + - ARLAS_CACHE_FACTORY_CLASS="${ARLAS_CACHE_FACTORY_CLASS:-io.arlas.server.core.impl.cache.CollectionLocalCacheFactory}" - ARLAS_CACHE_TIMEOUT="${ARLAS_CACHE_TIMEOUT:-5}" - ARLAS_SWAGGER_RESOURCE_PKG="${ARLAS_SWAGGER_RESOURCE_PKG:-io.arlas.server.rest}" ports: diff --git a/docs/arlas-server-configuration.md b/docs/arlas-server-configuration.md index 1937fd4eb..058793d28 100644 --- a/docs/arlas-server-configuration.md +++ b/docs/arlas-server-configuration.md @@ -110,17 +110,17 @@ Refer to [ARLAS IAM configuration](arlas-iam.md) for a comprehensive configurati ### Collection Cache & Disovery -| Environment variable | ARLAS Server configuration variable | Default | Description | -|----------------------------------------|---------------------------------------------------------|---------------------------------------------------|----------------------------------------------------------------------| -| ARLAS_CACHE_FACTORY_CLASS | Cache manager class | io.arlas.server.core.impl.cache.LocalCacheFactory | Class to be used for the cache manager | -| ARLAS_CACHE_SIZE | arlas-cache-size | 1000 | Size of the cache used for managing the collections | -| ARLAS_CACHE_TIMEOUT | arlas-cache-timeout | 60 | Number of seconds for the cache used for managing the collections | -| ARLAS_REST_CACHE_TIMEOUT | arlas-rest-cache-timeout | 0 | Number of seconds for the cache used for managing the REST responses | -| ARLAS_COLLECTION_AUTODISCOVER_SCHEDULE | collection-auto-discover.schedule | 0 | Number of seconds between two auto discovery tasks | -| N/A | collection-auto-discover.preferred-id-field-name | id,identifier | Name of the id field for auto discovery | -| N/A | collection-auto-discover.preferred-timestamp-field-name | params.startdate | Name of the timestamp field for auto discovery | -| N/A | collection-auto-discover.preferred-centroid-field-name | geo_params.centroid | Name of the centroid field for auto discovery | -| N/A | collection-auto-discover.preferred-geometry-field-name | geo,geo_params.geometry | Name of the geometry field for auto discovery | +| Environment variable | ARLAS Server configuration variable | Default | Description | +|----------------------------------------|---------------------------------------------------------|-------------------------------------------------------------|----------------------------------------------------------------------| +| ARLAS_CACHE_FACTORY_CLASS | Cache manager class | io.arlas.server.core.impl.cache.CollectionLocalCacheFactory | Class to be used for the cache manager | +| ARLAS_CACHE_SIZE | arlas-cache-size | 1000 | Size of the cache used for managing the collections | +| ARLAS_CACHE_TIMEOUT | arlas-cache-timeout | 60 | Number of seconds for the cache used for managing the collections | +| ARLAS_REST_CACHE_TIMEOUT | arlas-rest-cache-timeout | 0 | Number of seconds for the cache used for managing the REST responses | +| ARLAS_COLLECTION_AUTODISCOVER_SCHEDULE | collection-auto-discover.schedule | 0 | Number of seconds between two auto discovery tasks | +| N/A | collection-auto-discover.preferred-id-field-name | id,identifier | Name of the id field for auto discovery | +| N/A | collection-auto-discover.preferred-timestamp-field-name | params.startdate | Name of the timestamp field for auto discovery | +| N/A | collection-auto-discover.preferred-centroid-field-name | geo_params.centroid | Name of the centroid field for auto discovery | +| N/A | collection-auto-discover.preferred-geometry-field-name | geo,geo_params.geometry | Name of the geometry field for auto discovery | ### Server