From 7bf7c3c03fd3a1efeaf3f8e3dd75922e2f5f9921 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 8 Mar 2022 19:06:10 +0100 Subject: refactor(core): move all project libs into sub-project 'modules' --- .../core/storage/CacheWithEidasBackend.java | 35 ++++ .../EidasCacheTransactionStoreDecorator.java | 180 +++++++++++++++++++++ .../storage/SimpleInMemoryTransactionStorage.java | 169 +++++++++++++++++++ .../core/storage/TransactionStoreElement.java | 70 ++++++++ 4 files changed, 454 insertions(+) create mode 100644 modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/CacheWithEidasBackend.java create mode 100644 modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java create mode 100644 modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/SimpleInMemoryTransactionStorage.java create mode 100644 modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/TransactionStoreElement.java (limited to 'modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage') diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/CacheWithEidasBackend.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/CacheWithEidasBackend.java new file mode 100644 index 00000000..0eeb35d9 --- /dev/null +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/CacheWithEidasBackend.java @@ -0,0 +1,35 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * 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. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.asitplus.eidas.specific.core.storage; + +import eu.eidas.auth.commons.cache.ConcurrentCacheService; +import eu.eidas.auth.commons.tx.AbstractCache; + +public class CacheWithEidasBackend extends AbstractCache { + + protected CacheWithEidasBackend(ConcurrentCacheService concurrentMapService) { + super(concurrentMapService); + } + +} diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java new file mode 100644 index 00000000..5a59a4e0 --- /dev/null +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java @@ -0,0 +1,180 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * 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. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.asitplus.eidas.specific.core.storage; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; +import at.gv.egiz.eaaf.core.impl.utils.Random; + +public class EidasCacheTransactionStoreDecorator implements ITransactionStorage, HealthIndicator { + private static final Logger log = LoggerFactory.getLogger(EidasCacheTransactionStoreDecorator.class); + + @Autowired(required = true) + private CacheWithEidasBackend storage; + + @Override + public Health health() { + try { + final String key = Random.nextHexRandom16(); + final String value = Random.nextHexRandom16(); + + this.put(key, value, -1); + final String result = this.get(key, String.class); + this.remove(key); + + if (result != null && result.equals(value)) { + return Health.up().build(); + + } else { + log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test"); + return Health.down().build(); + + } + + } catch (final EaafException e) { + log.warn("Montioring: Can not read/write to storage.", e); + return Health.down().down(e).build(); + + } + } + + @Override + public void changeKey(String oldKey, String newKey, Object value) throws EaafException { + if (containsKey(oldKey)) { + final TransactionStoreElement el = storage.get(oldKey); + el.setKey(newKey); + el.setData(value); + storage.put(newKey, el); + boolean delResult = storage.remove(oldKey); + log.trace("Object: {} removed from cache: {}", oldKey, delResult); + + } else { + throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); + } + + } + + @Override + public List clean(Date now, long dataTimeOut) { + log.info("Clean is NOT implemented, because its not needed"); + return Arrays.asList(); + + } + + @Override + public boolean containsKey(String key) { + return storage.containsKey(key); + + } + + @Override + public Object get(String key) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement element = storage.get(key); + return element.getData(); + + } else { + return null; + } + } + + @Override + public T get(String key, Class type) throws EaafException { + return get(key, type, -1); + + } + + @Override + public T get(String key, Class type, long dataTimeOut) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement value = storage.get(key); + + if (dataTimeOut > -1) { + final long now = new Date().getTime(); + if (now - value.getCreated().getTime() > dataTimeOut) { + log.info("Transaction-Data with key: " + key + " is out of time."); + throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); + + } + } + + if (type.isAssignableFrom(value.getData().getClass())) { + return (T) value.getData(); + + } else { + log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); + } + + } + + return null; + } + + @Override + public Object getRaw(String key) throws EaafException { + return storage.get(key); + + } + + @Override + public void put(String key, Object value, int dataTimeOut) throws EaafException { + final TransactionStoreElement element = new TransactionStoreElement(); + element.setKey(key); + element.setData(value); + storage.put(key, element); + + } + + @Override + public void putRaw(String key, Object value) throws EaafException { + if (value instanceof TransactionStoreElement) { + storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); + } else { + log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class + .getName()); + } + + } + + @Override + public void remove(String key) { + if (containsKey(key)) { + log.trace("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); + boolean delResult = storage.remove(key); + log.trace("Object: {} removed from cache: {}", key, delResult); + + } + } +} diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/SimpleInMemoryTransactionStorage.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/SimpleInMemoryTransactionStorage.java new file mode 100644 index 00000000..a3a8af0f --- /dev/null +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/SimpleInMemoryTransactionStorage.java @@ -0,0 +1,169 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * 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. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.asitplus.eidas.specific.core.storage; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; + +public class SimpleInMemoryTransactionStorage implements ITransactionStorage { + private static final Logger log = LoggerFactory.getLogger(SimpleInMemoryTransactionStorage.class); + + private final Map storage = + new ConcurrentHashMap<>(); + + @Override + public void changeKey(String oldKey, String newKey, Object value) throws EaafException { + if (containsKey(oldKey)) { + final TransactionStoreElement el = storage.get(oldKey); + el.setKey(newKey); + storage.put(newKey, el); + storage.remove(oldKey); + + } else { + throw new EaafStorageException("No element in TransactionStorage with key: " + oldKey); + } + + } + + @Override + public List clean(Date now, long dataTimeOut) { + final List result = new ArrayList<>(); + final Iterator> iterator = storage.entrySet().iterator(); + while (iterator.hasNext()) { + final Entry key = iterator.next(); + synchronized (storage) { + if (storage.containsKey(key.getKey())) { + final TransactionStoreElement element = key.getValue(); + if (now.getTime() - element.getCreated().getTime() > dataTimeOut) { + result.add(key.getKey()); + } + } + } + } + + return result; + + } + + @Override + public boolean containsKey(String key) { + if (key != null) { + return storage.containsKey(key); + } else { + return false; + } + + } + + @Override + public Object get(String key) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement element = storage.get(key); + return element.getData(); + + } else { + return null; + } + } + + @Override + public T get(String key, Class type) throws EaafException { + return get(key, type, -1); + + } + + @Override + public T get(String key, Class type, long dataTimeOut) throws EaafException { + if (key != null && containsKey(key)) { + final TransactionStoreElement value = storage.get(key); + + if (dataTimeOut > -1) { + final long now = new Date().getTime(); + if (now - value.getCreated().getTime() > dataTimeOut) { + log.info("Transaction-Data with key: " + key + " is out of time."); + throw new EaafStorageException("Transaction-Data with key: " + key + " is out of time."); + + } + } + + if (type.isAssignableFrom(value.getData().getClass())) { + return (T) value.getData(); + + } else { + log.warn("Can NOT cast '" + value.getClass() + "' to '" + type + "'"); + } + + } + + return null; + } + + @Override + public Object getRaw(String key) throws EaafException { + return storage.get(key); + + } + + @Override + public void put(String key, Object value, int dataTimeOut) throws EaafException { + final TransactionStoreElement element = new TransactionStoreElement(); + element.setKey(key); + element.setData(value); + storage.put(key, element); + + } + + @Override + public void putRaw(String key, Object value) throws EaafException { + if (value instanceof TransactionStoreElement) { + storage.put(((TransactionStoreElement) value).getKey(), (TransactionStoreElement) value); + } else { + log.info(value.getClass().getName() + " is NOT a RAW element of " + ITransactionStorage.class + .getName()); + } + + } + + @Override + public void remove(String key) { + if (containsKey(key)) { + log.debug("Remove element with key: " + key + " from " + ITransactionStorage.class.getName()); + storage.remove(key); + + } + } + +} diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/TransactionStoreElement.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/TransactionStoreElement.java new file mode 100644 index 00000000..48668d4b --- /dev/null +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/TransactionStoreElement.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * 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. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. +*/ + +package at.asitplus.eidas.specific.core.storage; + +import java.io.Serializable; +import java.util.Date; + +public class TransactionStoreElement implements Serializable { + + private static final long serialVersionUID = 1L; + private String key = null; + private Object data = null; + private Date created; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public Date getCreated() { + return copyOrNull(created); + } + + public void setCreated(Date created) { + this.created = copyOrNull(created); + } + + private Date copyOrNull(Date in) { + if (in != null) { + return new Date(in.getTime()); + + } + + return null; + + } + +} -- cgit v1.2.3 From ac8f3011f2278c1c02e59f7cc1054b7d0168b034 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 7 Jul 2022 11:43:09 +0200 Subject: chore(cache): catch a more generic exception in Transaction-Cache health check --- .../specific/core/storage/EidasCacheTransactionStoreDecorator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage') diff --git a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java index 5a59a4e0..44547d95 100644 --- a/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java +++ b/modules/core_common_webapp/src/main/java/at/asitplus/eidas/specific/core/storage/EidasCacheTransactionStoreDecorator.java @@ -63,7 +63,7 @@ public class EidasCacheTransactionStoreDecorator implements ITransactionStorage, } - } catch (final EaafException e) { + } catch (final Exception e) { log.warn("Montioring: Can not read/write to storage.", e); return Health.down().down(e).build(); -- cgit v1.2.3