From a50094ec323141be6b0063408942c0dfabf96218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 28 Nov 2025 16:42:22 +0100 Subject: [PATCH 01/45] fix not to stop caching service during the start-up because of a connection issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../zowe/apiml/caching/service/Messages.java | 3 +- .../infinispan/config/InfinispanConfig.java | 34 +++++++++++++------ .../infinispan/storage/InfinispanStorage.java | 19 ++++++++--- .../main/resources/caching-log-messages.yml | 8 +++++ 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/Messages.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/Messages.java index b2446d0c81..38e7d9859c 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/Messages.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/Messages.java @@ -26,7 +26,8 @@ public enum Messages { PAYLOAD_TOO_LARGE("org.zowe.apiml.cache.payloadTooLarge", HttpStatus.BAD_REQUEST), INTERNAL_SERVER_ERROR("org.zowe.apiml.common.internalRequestError", HttpStatus.INTERNAL_SERVER_ERROR), MISSING_CERTIFICATE("org.zowe.apiml.cache.missingCertificate", HttpStatus.UNAUTHORIZED), - INCOMPATIBLE_STORAGE_METHOD("org.zowe.apiml.cache.incompatibleStorageMethod", HttpStatus.BAD_REQUEST); + INCOMPATIBLE_STORAGE_METHOD("org.zowe.apiml.cache.incompatibleStorageMethod", HttpStatus.BAD_REQUEST), + CACHE_NOT_AVAILABLE("org.zowe.apiml.cache.notAvailable", HttpStatus.SERVICE_UNAVAILABLE); private final String key; private final HttpStatus status; } diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 032f6eabe5..35aabe21c4 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -10,6 +10,7 @@ package org.zowe.apiml.caching.service.infinispan.config; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.infinispan.commons.api.CacheContainerAdmin; import org.infinispan.commons.dataconversion.MediaType; @@ -21,22 +22,27 @@ import org.infinispan.lock.api.ClusteredLock; import org.infinispan.lock.api.ClusteredLockManager; import org.infinispan.manager.DefaultCacheManager; +import org.infinispan.partitionhandling.AvailabilityException; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; +import org.zowe.apiml.caching.service.Messages; import org.zowe.apiml.caching.service.Storage; +import org.zowe.apiml.caching.service.StorageException; import org.zowe.apiml.caching.service.infinispan.exception.InfinispanConfigException; import org.zowe.apiml.caching.service.infinispan.storage.InfinispanStorage; -import static org.zowe.apiml.security.SecurityUtils.formatKeyringUrl; -import static org.zowe.apiml.security.SecurityUtils.isKeyring; import javax.annotation.PostConstruct; import java.io.IOException; import java.io.InputStream; +import static org.zowe.apiml.security.SecurityUtils.formatKeyringUrl; +import static org.zowe.apiml.security.SecurityUtils.isKeyring; + +@Slf4j @Configuration @ConfigurationProperties(value = "caching.storage.infinispan") @ConditionalOnProperty(name = "caching.storage.mode", havingValue = "infinispan") @@ -108,17 +114,25 @@ DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { return cacheManager; } - @Bean - public ClusteredLock lock(DefaultCacheManager cacheManager) { - ClusteredLockManager clm = EmbeddedClusteredLockManagerFactory.from(cacheManager); - clm.defineLock("zoweInvalidatedTokenLock"); - return clm.get("zoweInvalidatedTokenLock"); + private ClusteredLock lock(DefaultCacheManager cacheManager) { + try { + ClusteredLockManager clm = EmbeddedClusteredLockManagerFactory.from(cacheManager); + // it can throw AvailabilityException + clm.defineLock("zoweInvalidatedTokenLock"); + return clm.get("zoweInvalidatedTokenLock"); + } catch (AvailabilityException ae) { + log.debug("Cannot obtain lock", ae); + throw new StorageException(Messages.CACHE_NOT_AVAILABLE.getKey(), Messages.CACHE_NOT_AVAILABLE.getStatus()); + } } - @Bean - public Storage storage(DefaultCacheManager cacheManager, ClusteredLock clusteredLock) { - return new InfinispanStorage(cacheManager.getCache("zoweCache"), cacheManager.getCache("zoweInvalidatedTokenCache"), clusteredLock); + public Storage storage(DefaultCacheManager cacheManager) { + return new InfinispanStorage( + cacheManager.getCache("zoweCache"), + cacheManager.getCache("zoweInvalidatedTokenCache"), + () -> lock(cacheManager) + ); } } diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java index 28dfe31414..1e44474a5c 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java @@ -24,7 +24,11 @@ import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.stream.Collectors; @Slf4j @@ -33,13 +37,17 @@ public class InfinispanStorage implements Storage { private final ConcurrentMap cache; private final ConcurrentMap> tokenCache; - private final ClusteredLock lock; + private final Supplier lockSupplier; private static final ObjectMapper objectMapper = new ObjectMapper(); - public InfinispanStorage(ConcurrentMap cache, ConcurrentMap> tokenCache, ClusteredLock lock) { + public InfinispanStorage( + ConcurrentMap cache, + ConcurrentMap> tokenCache, + Supplier lockSupplier + ) { this.cache = cache; this.tokenCache = tokenCache; - this.lock = lock; + this.lockSupplier = lockSupplier; } static { @@ -61,6 +69,7 @@ public KeyValue create(String serviceId, KeyValue toCreate) { @Override public KeyValue storeMapItem(String serviceId, String mapKey, KeyValue toCreate) { + ClusteredLock lock = lockSupplier.get(); CompletableFuture complete = lock.tryLock(4, TimeUnit.SECONDS).whenComplete((r, ex) -> { if (Boolean.TRUE.equals(r)) { try { @@ -154,6 +163,7 @@ public void deleteForService(String serviceId) { @Override public void removeNonRelevantTokens(String serviceId, String mapKey) { + ClusteredLock lock = lockSupplier.get(); CompletableFuture complete = lock.tryLock(4, TimeUnit.SECONDS).whenComplete((r, ex) -> { if (Boolean.TRUE.equals(r)) { try { @@ -184,6 +194,7 @@ private void removeToken(String serviceId, String mapKey) { @Override public void removeNonRelevantRules(String serviceId, String mapKey) { + ClusteredLock lock = lockSupplier.get(); CompletableFuture complete = lock.tryLock(4, TimeUnit.SECONDS).whenComplete((r, ex) -> { if (Boolean.TRUE.equals(r)) { try { diff --git a/caching-service/src/main/resources/caching-log-messages.yml b/caching-service/src/main/resources/caching-log-messages.yml index 5565289d03..ec6ccb0f2b 100644 --- a/caching-service/src/main/resources/caching-log-messages.yml +++ b/caching-service/src/main/resources/caching-log-messages.yml @@ -114,3 +114,11 @@ messages: text: "Missing header with certificate." reason: "Call executed without valid client certificate." action: "Verify ssl context in client application." + + - key: org.zowe.apiml.cache.notAvailable + number: ZWECS703 + type: WARNING + text: "Cache is not available." + reason: "Cache is not ready to write add the moment." + action: "Verify the instance configuration or connectivity between multiple instances." + From ead581be71274d2638c357b12082f2b2d1f3a995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 28 Nov 2025 16:54:52 +0100 Subject: [PATCH 02/45] code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../caching/service/infinispan/config/InfinispanConfig.java | 2 +- caching-service/src/main/resources/caching-log-messages.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 35aabe21c4..7bf23ef1b5 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -122,7 +122,7 @@ private ClusteredLock lock(DefaultCacheManager cacheManager) { return clm.get("zoweInvalidatedTokenLock"); } catch (AvailabilityException ae) { log.debug("Cannot obtain lock", ae); - throw new StorageException(Messages.CACHE_NOT_AVAILABLE.getKey(), Messages.CACHE_NOT_AVAILABLE.getStatus()); + throw new StorageException(Messages.CACHE_NOT_AVAILABLE.getKey(), Messages.CACHE_NOT_AVAILABLE.getStatus(), ae.getMessage()); } } diff --git a/caching-service/src/main/resources/caching-log-messages.yml b/caching-service/src/main/resources/caching-log-messages.yml index ec6ccb0f2b..82bf156b02 100644 --- a/caching-service/src/main/resources/caching-log-messages.yml +++ b/caching-service/src/main/resources/caching-log-messages.yml @@ -118,7 +118,7 @@ messages: - key: org.zowe.apiml.cache.notAvailable number: ZWECS703 type: WARNING - text: "Cache is not available." - reason: "Cache is not ready to write add the moment." + text: "Cache is not available: %s" + reason: "Cache is not ready to write at the moment." action: "Verify the instance configuration or connectivity between multiple instances." From 312ffff7b4d252da4cf2174d94212d9c2a7c9dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 28 Nov 2025 17:04:39 +0100 Subject: [PATCH 03/45] test fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../storage/InfinispanStorageTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/caching-service/src/test/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorageTest.java b/caching-service/src/test/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorageTest.java index 09c4a5c10b..00fd9a924b 100644 --- a/caching-service/src/test/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorageTest.java +++ b/caching-service/src/test/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorageTest.java @@ -46,8 +46,8 @@ class InfinispanStorageTest { void setup() { cache = mock(Cache.class); tokenCache = mock(AdvancedCache.class); - storage = new InfinispanStorage(cache, tokenCache, lock); lock = mock(ClusteredLock.class); + storage = new InfinispanStorage(cache, tokenCache, () -> lock); } @Nested @@ -124,7 +124,7 @@ void cacheIsUpdated() { @Test void itemIsDeleted() { ConcurrentMap cache = new ConcurrentHashMap<>(); - InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, lock); + InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, () -> lock); assertNull(storage.create(serviceId1, TO_CREATE)); assertEquals(TO_CREATE, storage.delete(serviceId1, TO_CREATE.getKey())); } @@ -132,7 +132,7 @@ void itemIsDeleted() { @Test void returnAll() { ConcurrentMap cache = new ConcurrentHashMap<>(); - InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, lock); + InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, () -> lock); storage.create(serviceId1, new KeyValue("key", "value")); storage.create(serviceId1, new KeyValue("key2", "value2")); assertEquals(2, storage.readForService(serviceId1).size()); @@ -141,7 +141,7 @@ void returnAll() { @Test void removeAll() { ConcurrentMap cache = new ConcurrentHashMap<>(); - InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, lock); + InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, () -> lock); storage.create(serviceId1, new KeyValue("key", "value")); storage.create(serviceId1, new KeyValue("key2", "value2")); assertEquals(2, storage.readForService(serviceId1).size()); @@ -173,7 +173,7 @@ void createStoreWithEntry() { void addToken() { HashMap hashMap = new HashMap<>(); hashMap.put("key", "token"); - InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, lock); + InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, () -> lock); when(tokenCache.get(anyString())).thenAnswer(invocation -> hashMap); assertNull(storage.storeMapItem(serviceId1, "invalidTokens", new KeyValue("newkey", "newvalue"))); verify(tokenCache, times(1)).put(serviceId1 + "invalidTokens", hashMap); @@ -183,7 +183,7 @@ void addToken() { void updateToken() { HashMap hashMap = new HashMap(); hashMap.put("key", "token"); - InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, lock); + InfinispanStorage storage = new InfinispanStorage(cache, tokenCache, () -> lock); when(tokenCache.get(serviceId1 + "invalidTokens")).thenReturn(hashMap); KeyValue keyValue = new KeyValue("key", "token2"); assertNull(storage.storeMapItem(serviceId1, "invalidTokens", keyValue)); @@ -223,7 +223,7 @@ void createStorage() { tokenCache.put(serviceId1 + "invalidTokens", tokensService1); tokenCache.put(serviceId1 + "invalidTokenRules", rulesService1); tokenCache.put(serviceId2 + "invalidTokens", tokensService2); - underTest = new InfinispanStorage(cache, tokenCache, lock); + underTest = new InfinispanStorage(cache, tokenCache, () -> lock); } @@ -275,7 +275,7 @@ void createStorage() { tokenCache.put(serviceId1 + "invalidTokens", tokensService); tokenCache.put(serviceId1 + "invalidScopes", rulesService); tokenCache.put(serviceId1 + "invalidUsers", rulesUsers); - underTest = new InfinispanStorage(cache, tokenCache, lock); + underTest = new InfinispanStorage(cache, tokenCache, () -> lock); } @Test void thenEvictItems() { From 36215b2520a1bee8bed6df5ddf27751456a91b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 29 Jan 2025 13:11:48 +0100 Subject: [PATCH 04/45] cherry-pick of fix "Use HA instance ID in path to infinispan storage location (v3)" #3960 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../infinispan/config/InfinispanConfig.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 7bf23ef1b5..8f718030cb 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -38,6 +38,7 @@ import javax.annotation.PostConstruct; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Paths; import static org.zowe.apiml.security.SecurityUtils.formatKeyringUrl; import static org.zowe.apiml.security.SecurityUtils.isKeyring; @@ -77,7 +78,22 @@ void updateKeyring() { } } - @Bean + static String getRootFolder() { + // using getenv().get is because of system compatibility (see non-case sensitive on Windows) + String instanceId = System.getenv().get("ZWE_haInstance_id"); + if (StringUtils.isBlank(instanceId)) { + instanceId = "localhost"; + } + + String workspaceFolder = System.getenv().get("ZWE_zowe_workspaceDirectory"); + if (StringUtils.isBlank(workspaceFolder)) { + return Paths.get("caching-service", instanceId).toString(); + } else { + return Paths.get(workspaceFolder, "caching-service", instanceId).toString(); + } + } + + @Bean(destroyMethod = "stop") DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { System.setProperty("jgroups.tcpping.initial_hosts", initialHosts); System.setProperty("jgroups.bind.port", port); @@ -94,6 +110,9 @@ DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { } catch (IOException e) { throw new InfinispanConfigException("Can't read configuration file", e); } + holder.getGlobalConfigurationBuilder().globalState().persistentLocation(getRootFolder()).enable(); + holder.newConfigurationBuilder("default").persistence().passivation(true).addSoftIndexFileStore() + .shared(false); DefaultCacheManager cacheManager = new DefaultCacheManager(holder, true); From 6517fd5d7895b39d427e960db56ed5a8022934d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Mon, 1 Dec 2025 14:07:33 +0100 Subject: [PATCH 05/45] cherry-pick of fix "disable infinispan diagnostics by default" #4157 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- caching-service-package/src/main/resources/bin/start.sh | 1 + .../caching/service/infinispan/config/InfinispanConfig.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/caching-service-package/src/main/resources/bin/start.sh b/caching-service-package/src/main/resources/bin/start.sh index 6cb4d1cf14..439ad58fa7 100755 --- a/caching-service-package/src/main/resources/bin/start.sh +++ b/caching-service-package/src/main/resources/bin/start.sh @@ -265,6 +265,7 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${CACHING_CODE} java \ -Djgroups.bind.address=${ZWE_haInstance_hostname:-localhost} \ -Djgroups.bind.port=${ZWE_configs_storage_infinispan_jgroups_port:-7098} \ -Djgroups.keyExchange.port=${ZWE_configs_storage_infinispan_jgroups_keyExchange_port:-7118} \ + -Djgroups.tcp.diag.enabled=${ZWE_configs_storage_infinispan_jgroups_tcp_diag_enabled:-false} \ -Dcaching.storage.infinispan.persistence.dataLocation=${ZWE_configs_storage_infinispan_persistence_dataLocation:-data} \ -Dcaching.storage.infinispan.persistence.indexLocation=${ZWE_configs_storage_infinispan_persistence_indexLocation:-index} \ -Dcaching.storage.infinispan.initialHosts=${ZWE_configs_storage_infinispan_initialHosts:-localhost[7098]} \ diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 8f718030cb..7b3df551f3 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -69,6 +69,8 @@ public class InfinispanConfig { private String address; @Value("${jgroups.keyExchange.port:7118}") private String keyExchangePort; + @Value("${jgroups.tcp.diag.enabled:false}") + private String tcpDiagEnabled; @PostConstruct void updateKeyring() { @@ -102,6 +104,7 @@ DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { System.setProperty("server.ssl.keyStoreType", keyStoreType); System.setProperty("server.ssl.keyStore", keyStore); System.setProperty("server.ssl.keyStorePassword", keyStorePass); + System.setProperty("jgroups.tcp.diag.enabled", String.valueOf(Boolean.parseBoolean(tcpDiagEnabled))); ConfigurationBuilderHolder holder; try (InputStream configurationStream = resourceLoader.getResource( From 6d4352578eba054d425a8b96504981357fb2da3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 10:31:37 +0100 Subject: [PATCH 06/45] fix Eureka period to 30s from 1s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- caching-service/src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/caching-service/src/main/resources/application.yml b/caching-service/src/main/resources/application.yml index 0f7a99723e..4a0618929e 100644 --- a/caching-service/src/main/resources/application.yml +++ b/caching-service/src/main/resources/application.yml @@ -41,8 +41,8 @@ logging: javax.net.ssl: ERROR # For running with java 17 eureka: client: - initialInstanceInfoReplicationIntervalSeconds: 1 - registryFetchIntervalSeconds: 1 + initialInstanceInfoReplicationIntervalSeconds: 30 + registryFetchIntervalSeconds: 30 apiml: enabled: true service: From 19aef22e84408e6ad11ff853b122b7caa0890205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 10:32:03 +0100 Subject: [PATCH 07/45] add debug message about salt issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../gateway/security/service/token/ApimlAccessTokenProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java index a10561d3f6..d550941c89 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java @@ -153,6 +153,7 @@ private String initializeSalt() throws CachingServiceClientException { CachingServiceClient.KeyValue keyValue = cachingServiceClient.read("salt"); localSalt = keyValue.getValue(); } catch (CachingServiceClientException e) { + log.debug("Cannot read salt.", e); byte[] newSalt = generateSalt(); storeSalt(newSalt); localSalt = new String(newSalt); From e1a967bc40336532723d85eeee3b0c320f3cdbfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= <58428711+pj892031@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:16:51 +0200 Subject: [PATCH 08/45] fix: Fix detection of connection issue (#4142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../eureka/client/ApimlPeerEurekaNode.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java b/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java index 95ccea9c0f..50e0689059 100644 --- a/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java +++ b/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java @@ -560,13 +560,15 @@ private static boolean isSuccess(int statusCode) { * @return true, if it is a network timeout, false otherwise. */ private static boolean isNetworkConnectException(Throwable e) { - do { - if (e instanceof IOException && !(e instanceof SSLException)) { - return true; - } - e = e.getCause(); - } while (e != null); - return false; + if (e instanceof IOException && !(e instanceof SSLException)) { + return true; + } + + var cause = e.getCause(); + if ((cause == null) || (cause == e)) { + return false; + } + return isNetworkConnectException(cause); } /** @@ -576,17 +578,21 @@ private static boolean isNetworkConnectException(Throwable e) { * @return true, if it may be a socket read time out exception. */ private static boolean maybeReadTimeOut(Throwable e) { - do { - if (e instanceof IOException) { - String message = e.getMessage().toLowerCase(); - Matcher matcher = READ_TIME_OUT_PATTERN.matcher(message); + if (e instanceof IOException) { + String message = e.getMessage(); + if (message != null) { + Matcher matcher = READ_TIME_OUT_PATTERN.matcher(message.toLowerCase()); if (matcher.find()) { return true; } } - e = e.getCause(); - } while (e != null); - return false; + } + + var cause = e.getCause(); + if ((cause == null) || (cause == e)) { + return false; + } + return maybeReadTimeOut(cause); } From 4c037324fbe56efaf74bc93768863163f43f9e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 10:35:12 +0100 Subject: [PATCH 09/45] compilation fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java b/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java index 50e0689059..f5aad7b1b7 100644 --- a/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java +++ b/apiml-common/src/main/java/org/zowe/apiml/product/eureka/client/ApimlPeerEurekaNode.java @@ -564,7 +564,7 @@ private static boolean isNetworkConnectException(Throwable e) { return true; } - var cause = e.getCause(); + Throwable cause = e.getCause(); if ((cause == null) || (cause == e)) { return false; } @@ -588,7 +588,7 @@ private static boolean maybeReadTimeOut(Throwable e) { } } - var cause = e.getCause(); + Throwable cause = e.getCause(); if ((cause == null) || (cause == e)) { return false; } From d0c4b715e08e982c2f107750d1310201551b0216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 12:27:38 +0100 Subject: [PATCH 10/45] migration step of infinispan storage location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../src/main/resources/bin/start.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/caching-service-package/src/main/resources/bin/start.sh b/caching-service-package/src/main/resources/bin/start.sh index 439ad58fa7..d9b81d1ddd 100755 --- a/caching-service-package/src/main/resources/bin/start.sh +++ b/caching-service-package/src/main/resources/bin/start.sh @@ -238,6 +238,16 @@ if [ "${ATTLS_ENABLED}" = "true" -a "${APIML_ATTLS_LOAD_KEYRING:-false}" = "true keystore_location= fi +# migration step of Infinispan since version 2.18.4 (see #https://github.com/zowe/api-layer/pull/3960) +original_infinispan_data_location="${ZWE_configs_storage_infinispan_persistence_dataLocation:-${ZWE_zowe_workspaceDirectory:-$(pwd)}}/caching-service/data" +if [ -d "${original_infinispan_data_location}" ]; then + mv -f "${original_infinispan_data_location}" "${ZWE_zowe_workspaceDirectory:-$(pwd)}/caching-service/${ZWE_haInstance_id:-localhost}/${ZWE_configs_storage_infinispan_persistence_dataLocation:-data}" +fi +original_infinispan_index_location="${ZWE_configs_storage_infinispan_persistence_indexLocation:-${ZWE_zowe_workspaceDirectory:-$(pwd)}}/caching-service/index" +if [ -d "${original_infinispan_index_location}" ]; then + mv -f "${original_infinispan_index_location}" "${ZWE_zowe_workspaceDirectory:-$(pwd)}/caching-service/${ZWE_haInstance_id:-localhost}/${ZWE_configs_storage_infinispan_persistence_indexLocation:-index}" +fi + CACHING_CODE=CS _BPXK_AUTOCVT=OFF _BPX_JOBNAME=${ZWE_zowe_job_prefix}${CACHING_CODE} java \ From a70aa09043fa5871fa19374ae6b6e4d8e205b09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 12:34:00 +0100 Subject: [PATCH 11/45] lazy init of lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../infinispan/config/InfinispanConfig.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 7b3df551f3..479bc5fd69 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicReference; import static org.zowe.apiml.security.SecurityUtils.formatKeyringUrl; import static org.zowe.apiml.security.SecurityUtils.isKeyring; @@ -72,6 +73,8 @@ public class InfinispanConfig { @Value("${jgroups.tcp.diag.enabled:false}") private String tcpDiagEnabled; + private AtomicReference zoweInvalidatedTokenLock = new AtomicReference<>(); + @PostConstruct void updateKeyring() { if (isKeyring(keyStore)) { @@ -137,11 +140,23 @@ DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { } private ClusteredLock lock(DefaultCacheManager cacheManager) { + ClusteredLock lock = zoweInvalidatedTokenLock.get(); + if (lock != null) { + return lock; + } + try { - ClusteredLockManager clm = EmbeddedClusteredLockManagerFactory.from(cacheManager); - // it can throw AvailabilityException - clm.defineLock("zoweInvalidatedTokenLock"); - return clm.get("zoweInvalidatedTokenLock"); + synchronized (zoweInvalidatedTokenLock) { + lock = zoweInvalidatedTokenLock.get(); + if (lock == null) { + ClusteredLockManager clm = EmbeddedClusteredLockManagerFactory.from(cacheManager); + // it can throw AvailabilityException + clm.defineLock("zoweInvalidatedTokenLock"); + lock = clm.get("zoweInvalidatedTokenLock"); + } + zoweInvalidatedTokenLock.set(lock); + } + return lock; } catch (AvailabilityException ae) { log.debug("Cannot obtain lock", ae); throw new StorageException(Messages.CACHE_NOT_AVAILABLE.getKey(), Messages.CACHE_NOT_AVAILABLE.getStatus(), ae.getMessage()); From 59a43ace6374171b15f4cbe45d587b10be47c6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 16:03:10 +0100 Subject: [PATCH 12/45] add debug messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../java/org/zowe/apiml/caching/api/CachingController.java | 5 +++++ caching-service/src/main/resources/application.yml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java b/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java index b73250ca97..2051377e39 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java @@ -13,6 +13,7 @@ import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -28,6 +29,7 @@ import javax.servlet.http.HttpServletRequest; import java.util.Optional; +@Slf4j @RestController @RequiredArgsConstructor @RequestMapping("/api/v1") @@ -199,6 +201,7 @@ public ResponseEntity update(@RequestBody KeyValue keyValue, HttpServlet private ResponseEntity exceptionToResponse(StorageException exception) { + log.debug("Storage exception", exception); Message message = messageService.createMessage(exception.getKey(), (Object[]) exception.getParameters()); return new ResponseEntity<>(message.mapToView(), exception.getStatus()); } @@ -298,12 +301,14 @@ private Optional getHeader(HttpServletRequest request, String headerName } private ResponseEntity handleInternalError(Exception exception, StringBuffer requestURL) { + log.debug("Internal error occurred", exception); Messages internalServerError = Messages.INTERNAL_SERVER_ERROR; Message message = messageService.createMessage(internalServerError.getKey(), requestURL, exception.getMessage(), exception.toString()); return new ResponseEntity<>(message.mapToView(), internalServerError.getStatus()); } private ResponseEntity handleIncompatibleStorageMethod(Exception exception, StringBuffer requestURL) { + log.debug("Incompatible storage method", exception); Messages internalServerError = Messages.INCOMPATIBLE_STORAGE_METHOD; Message message = messageService.createMessage(internalServerError.getKey(), requestURL, exception.getMessage(), exception.toString()); return new ResponseEntity<>(message.mapToView(), internalServerError.getStatus()); diff --git a/caching-service/src/main/resources/application.yml b/caching-service/src/main/resources/application.yml index 4a0618929e..887e066374 100644 --- a/caching-service/src/main/resources/application.yml +++ b/caching-service/src/main/resources/application.yml @@ -173,6 +173,10 @@ logging: org.ehcache: INFO org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter: INFO com.netflix.discovery.shared.transport.decorator: DEBUG + org.apache.tomcat: DEBUG + org.apache.catalina: DEBUG + org.apache.coyote.http11.Http11InputBuffer: TRACE + org.infinispan: DEBUG --- spring: From e57b6486b5556fd8f5c5b7ff1429447a4ae8016f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 3 Dec 2025 16:10:07 +0100 Subject: [PATCH 13/45] stop caching of salt on Gateway side MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../security/service/token/ApimlAccessTokenProvider.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java index d550941c89..dc2580c518 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java @@ -49,8 +49,6 @@ public class ApimlAccessTokenProvider implements AccessTokenProvider { @Qualifier("oidcJwkMapper") private final ObjectMapper objectMapper; - private byte[] salt; - public void invalidateToken(String token) throws CachingServiceClientException, JsonProcessingException { String hashedValue = getHash(token); QueryResponse queryResponse = authenticationService.parseJwtWithSignature(token); @@ -181,11 +179,7 @@ public boolean isValidForScopes(String jwtToken, String serviceId) { } public byte[] getSalt() throws CachingServiceClientException { - if (this.salt != null) { - return this.salt; - } - this.salt = initializeSalt().getBytes(); - return this.salt; + return initializeSalt().getBytes(); } private void storeSalt(byte[] salt) throws CachingServiceClientException { From 032f3bc61a5290ef879c26b60baf6a6b54095c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 29 Jan 2025 13:11:48 +0100 Subject: [PATCH 14/45] fix infinispan diag configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- caching-service/src/main/resources/infinispan.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caching-service/src/main/resources/infinispan.xml b/caching-service/src/main/resources/infinispan.xml index cd297228b3..d80c07d6b6 100644 --- a/caching-service/src/main/resources/infinispan.xml +++ b/caching-service/src/main/resources/infinispan.xml @@ -5,7 +5,7 @@ Date: Mon, 8 Dec 2025 15:34:28 +0100 Subject: [PATCH 15/45] infinispan config improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../src/main/resources/bin/start.sh | 2 -- .../infinispan/config/InfinispanConfig.java | 16 +++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/caching-service-package/src/main/resources/bin/start.sh b/caching-service-package/src/main/resources/bin/start.sh index d9b81d1ddd..7ec277e7cf 100755 --- a/caching-service-package/src/main/resources/bin/start.sh +++ b/caching-service-package/src/main/resources/bin/start.sh @@ -276,8 +276,6 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${CACHING_CODE} java \ -Djgroups.bind.port=${ZWE_configs_storage_infinispan_jgroups_port:-7098} \ -Djgroups.keyExchange.port=${ZWE_configs_storage_infinispan_jgroups_keyExchange_port:-7118} \ -Djgroups.tcp.diag.enabled=${ZWE_configs_storage_infinispan_jgroups_tcp_diag_enabled:-false} \ - -Dcaching.storage.infinispan.persistence.dataLocation=${ZWE_configs_storage_infinispan_persistence_dataLocation:-data} \ - -Dcaching.storage.infinispan.persistence.indexLocation=${ZWE_configs_storage_infinispan_persistence_indexLocation:-index} \ -Dcaching.storage.infinispan.initialHosts=${ZWE_configs_storage_infinispan_initialHosts:-localhost[7098]} \ -Dserver.address=0.0.0.0 \ -Dserver.ssl.enabled=${ZWE_configs_server_ssl_enabled:-true} \ diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 479bc5fd69..f5c6dffea1 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -117,19 +117,17 @@ DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { throw new InfinispanConfigException("Can't read configuration file", e); } holder.getGlobalConfigurationBuilder().globalState().persistentLocation(getRootFolder()).enable(); - holder.newConfigurationBuilder("default").persistence().passivation(true).addSoftIndexFileStore() - .shared(false); + holder.newConfigurationBuilder("default").persistence() + .addSoftIndexFileStore() + .clustering().cacheMode(CacheMode.DIST_SYNC); DefaultCacheManager cacheManager = new DefaultCacheManager(holder, true); ConfigurationBuilder builder = new ConfigurationBuilder(); - builder.clustering().cacheMode(CacheMode.REPL_SYNC) - .encoding().mediaType("application/x-jboss-marshalling"); - - builder.persistence().passivation(true) - .addSoftIndexFileStore() - .shared(false) - .dataLocation(dataLocation).indexLocation(indexLocation); + builder + .encoding().mediaType("application/x-jboss-marshalling") + .persistence().addSoftIndexFileStore().clustering() + .clustering().cacheMode(CacheMode.DIST_SYNC); cacheManager.administration() .withFlags(CacheContainerAdmin.AdminFlag.VOLATILE) .getOrCreateCache("zoweCache", builder.build()); From 2d10631477d2bf756b0087b3fdabd2a1687d6faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Mon, 8 Dec 2025 15:35:24 +0100 Subject: [PATCH 16/45] fix handling response from caching service by gateway (see no record vs. timeout) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../gateway/cache/CachingServiceClient.java | 17 +++++++++++------ .../service/token/ApimlAccessTokenProvider.java | 5 +++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java index 0b8a50f11e..7533e0a0a9 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java @@ -16,10 +16,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; +import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @@ -147,11 +145,18 @@ public KeyValue read(String key) throws CachingServiceClientException { if (response != null && response.hasBody()) { //NOSONAR tests return null return response.getBody(); } else { - throw new CachingServiceClientException("Unable to read key: " + key + ", caused by response from caching service is null or has no body"); } } catch (RestClientException e) { - throw new CachingServiceClientException("Unable to read key: " + key + ", caused by: " + e.getMessage(), e); + if (!( + (e instanceof HttpStatusCodeException) && + (((HttpStatusCodeException) e).getStatusCode() == HttpStatus.NOT_FOUND) + )) { + throw new CachingServiceClientException("Unable to read key: " + key + ", caused by: " + e.getMessage(), e); + } } + + // record not found + throw new CachingServiceClientException("Unable to read key: " + key + ", caused by response from caching service is null or has no body"); } /** diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java index dc2580c518..0efa72b58e 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java @@ -152,6 +152,11 @@ private String initializeSalt() throws CachingServiceClientException { localSalt = keyValue.getValue(); } catch (CachingServiceClientException e) { log.debug("Cannot read salt.", e); + if (e.getCause() != null) { + // it could be because of timeout for example + throw e; + } + // a null value was returned byte[] newSalt = generateSalt(); storeSalt(newSalt); localSalt = new String(newSalt); From 2c3dd63b7243e2cb973e70c9dd65b4b05b663db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Mon, 8 Dec 2025 15:56:47 +0100 Subject: [PATCH 17/45] draft of IT of distributed cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- integration-tests/build.gradle | 1 + .../apiml/integration/ha/CachingService.java | 105 ++++++++++++++++++ .../config/CachingServiceConfiguration.java | 3 + .../environment-configuration-ha.yml | 3 + 4 files changed, 112 insertions(+) create mode 100644 integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java diff --git a/integration-tests/build.gradle b/integration-tests/build.gradle index 6bf20a20ab..fd5a39196c 100644 --- a/integration-tests/build.gradle +++ b/integration-tests/build.gradle @@ -36,6 +36,7 @@ dependencies { testImplementation libs.bcpkix; testImplementation project(':apiml-security-common') testImplementation project(':zaas-client') + testImplementation project(':caching-service') testImplementation libs.hamcrest testImplementation libs.awaitility diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java new file mode 100644 index 0000000000..073a8bfcbf --- /dev/null +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -0,0 +1,105 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +package org.zowe.apiml.integration.ha; + +import io.restassured.RestAssured; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.zowe.apiml.caching.model.KeyValue; +import org.zowe.apiml.util.categories.ChaoticHATest; +import org.zowe.apiml.util.config.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +import static io.restassured.RestAssured.given; +import static io.restassured.http.ContentType.JSON; +import static org.apache.http.HttpStatus.SC_OK; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.Is.is; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.zowe.apiml.util.config.ConfigReader.environmentConfiguration; + +@ChaoticHATest +@TestInstance(TestInstance.Lifecycle. PER_CLASS) +public class CachingService { + + private static final String SERVICE = "service"; + private static final String KEY = "aCacheKey" + new Random().nextInt(); + private static final String VALUE = "aCacheValue"; + + private static final KeyValue KEY_VALUE = new KeyValue(KEY, VALUE); + + private Credentials credentials; + private List baseUrls; + + @BeforeAll + void setUp() throws Exception { + RestAssured.useRelaxedHTTPSValidation(); + SslContext.prepareSslAuthentication(ItSslConfigFactory.integrationTests()); + + EnvironmentConfiguration environmentConfiguration = environmentConfiguration(); + CachingServiceConfiguration cachingServiceConfiguration = environmentConfiguration.getCachingServiceConfiguration(); + + KEY_VALUE.setServiceId(SERVICE); + + assumeTrue(cachingServiceConfiguration.getHost() != null); + baseUrls = Arrays.stream(cachingServiceConfiguration.getHost().split("[,;]")) + .map(host -> String.format("%s://%s:%d", cachingServiceConfiguration.getScheme(), host, cachingServiceConfiguration.getPort())) + .collect(Collectors.toList()); + credentials = ConfigReader.environmentConfiguration().getCredentials(); + } + + @Test + void testIt() { + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", SERVICE) + .contentType(JSON) + .body(KEY_VALUE) + .when() + .post(baseUrls.get(0) + "/cachingservice/api/v1/cache") + .then() + .statusCode(201); + + int instances = baseUrls.size(); + for (int i = -1; i < instances - 1; i++) { + if (i >= 0) { + // kill caching service + given() + .config(SslContext.clientCertApiml) + .contentType(JSON) + .auth().basic(credentials.getUser(), credentials.getPassword()) + .when() + .post(baseUrls.get(i) + "/cachingservice/application/shutdown") + .then() + .statusCode(is(SC_OK)); + } + + for (int j = i + 1; j < instances; j++) { + // check if the value is accessible + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", SERVICE) + .when() + .get(baseUrls.get(j) + "/cachingservice/api/v1/cache/" + KEY) + .then() + .statusCode(200) + .body("value", equalTo(VALUE)); + } + } + + } + +} diff --git a/integration-tests/src/test/java/org/zowe/apiml/util/config/CachingServiceConfiguration.java b/integration-tests/src/test/java/org/zowe/apiml/util/config/CachingServiceConfiguration.java index d5c8e1b156..040dda27e5 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/util/config/CachingServiceConfiguration.java +++ b/integration-tests/src/test/java/org/zowe/apiml/util/config/CachingServiceConfiguration.java @@ -19,4 +19,7 @@ @NoArgsConstructor public class CachingServiceConfiguration { private String url; + private String scheme; + private String host; + private int port; } diff --git a/integration-tests/src/test/resources/environment-configuration-ha.yml b/integration-tests/src/test/resources/environment-configuration-ha.yml index 1327309b2a..b0084415e6 100644 --- a/integration-tests/src/test/resources/environment-configuration-ha.yml +++ b/integration-tests/src/test/resources/environment-configuration-ha.yml @@ -34,6 +34,9 @@ apiCatalogServiceConfiguration: instances: 2 cachingServiceConfiguration: url: + scheme: https + host: caching-service,caching-service-2,caching-service-3 + port: 10016 cloudGatewayConfiguration: scheme: https host: cloud-gateway-service From 2bf3b87ecab338db26fc5943afa62b43eba0337c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 12:37:10 +0100 Subject: [PATCH 18/45] clean-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../java/org/zowe/apiml/gateway/cache/CachingServiceClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java index 7533e0a0a9..323b91cbd4 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/cache/CachingServiceClient.java @@ -144,7 +144,6 @@ public KeyValue read(String key) throws CachingServiceClientException { ResponseEntity response = restTemplate.exchange(gatewayProtocolHostPort + CACHING_API_PATH + "/" + key, HttpMethod.GET, new HttpEntity(null, defaultHeaders), KeyValue.class); if (response != null && response.hasBody()) { //NOSONAR tests return null return response.getBody(); - } else { } } catch (RestClientException e) { if (!( From 364d1b7da1b2b82ead4684e289d00ec3d3324e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 12:37:33 +0100 Subject: [PATCH 19/45] optimized usage of salt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../service/token/ApimlAccessTokenProvider.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java index 0efa72b58e..569a8c8db8 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java @@ -78,10 +78,11 @@ public void invalidateAllTokensForService(String serviceId, long timestamp) thro } public boolean isInvalidated(String token) throws CachingServiceClientException { + byte[] salt = getSalt(); QueryResponse parsedToken = authenticationService.parseJwtWithSignature(token); - String hashedToken = getHash(token); - String hashedUserId = getHash(parsedToken.getUserId().trim().toUpperCase()); - List hashedServiceIds = parsedToken.getScopes().stream().map(this::getHash).collect(Collectors.toList()); + String hashedToken = getHash(token, salt); + String hashedUserId = getHash(parsedToken.getUserId().trim().toUpperCase(), salt); + List hashedServiceIds = parsedToken.getScopes().stream().map(scope -> getHash(scope, salt)).collect(Collectors.toList()); Map> cacheMap = cachingServiceClient.readAllMaps(); if (cacheMap != null && !cacheMap.isEmpty()) { @@ -141,6 +142,10 @@ public void evictNonRelevantTokensAndRules() { cachingServiceClient.evictRules(INVALID_SCOPES_KEY); } + private String getHash(String token, byte[] salt) throws CachingServiceClientException { + return getSecurePassword(token, salt); + } + public String getHash(String token) throws CachingServiceClientException { return getSecurePassword(token, getSalt()); } From 8c3a3e41993f04f39a46e7bb178da2bf4db488fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 19 Nov 2025 10:21:32 +0100 Subject: [PATCH 20/45] fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../src/main/resources/bin/start.sh | 9 ++++- .../gateway/config/TomcatConfiguration.java | 38 ++++++++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/gateway-package/src/main/resources/bin/start.sh b/gateway-package/src/main/resources/bin/start.sh index 47777fb207..8ef7902b34 100755 --- a/gateway-package/src/main/resources/bin/start.sh +++ b/gateway-package/src/main/resources/bin/start.sh @@ -390,8 +390,13 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${GATEWAY_CODE} java \ -Dserver.internal.enabled=${ZWE_configs_server_internal_enabled:-false} \ -Dserver.internal.ssl.enabled=${ZWE_configs_server_internal_ssl_enabled:-true} \ -Dserver.internal.port=${ZWE_configs_server_internal_port:-10017} \ - -Dserver.internal.ssl.keyAlias=${ZWE_configs_server_internal_ssl_certificate_keystore_alias:-localhost-multi} \ - -Dserver.internal.ssl.keyStore=${ZWE_configs_server_internal_ssl_certificate_keystore_file:-keystore/localhost/localhost-multi.keystore.p12} \ + -Dserver.internal.ssl.keyAlias=${ZWE_configs_server_internal_ssl_certificate_keystore_alias:-${key_alias}} \ + -Dserver.internal.ssl.keyStore=${ZWE_configs_server_internal_ssl_certificate_keystore_file:-${keystore_location}} \ + -Dserver.internal.ssl.keyStoreType=${ZWE_configs_server_internal_ssl_certificate_keystoretype:-${keystore_type}} \ + -Dserver.internal.ssl.keyPassword=${ZWE_configs_server_internal_ssl_certificate_keypassword:-${key_pass}} \ + -Dserver.internal.ssl.trustStore=${ZWE_configs_server_internal_ssl_certificate_truststore_file:-${truststore_location}} \ + -Dserver.internal.ssl.trustStoreType=${ZWE_configs_server_internal_ssl_certificate_truststoretype:-${truststore_type}} \ + -Dserver.internal.ssl.trustStorePassword=${ZWE_configs_server_internal_ssl_certificate_truststorepassword:-${truststore_pass}} \ -Dapiml.httpclient.conn-pool.requestConnectionTimeout=${ZWE_configs_apiml_gateway_httpclient_requestConnectionTimeout:-10000} \ -Dapiml.security.auth.zosmf.jwtAutoconfiguration=${ZWE_configs_apiml_security_auth_zosmf_jwtAutoconfiguration:-auto} \ -Dapiml.security.jwtInitializerTimeout=${ZWE_configs_apiml_security_jwtInitializerTimeout:-5} \ diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java index c4182fa8f5..9c91d0a388 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java @@ -40,24 +40,28 @@ public class TomcatConfiguration { @Value("${server.internal.port:10017}") private int internalPort; - @Value("${server.internal.ssl.keyStore:keystore/localhost/localhost.keystore.p12}") + @Value("${server.internal.ssl.keyStore:${server.ssl.keyStore:#{null}}}") private String keyStorePath; - @Value("${server.internal.ssl.keyStorePassword:password}") + @Value("${server.internal.ssl.keyStorePassword:${server.ssl.keyStorePassword:#{null}}}") private String keyStorePassword; - @Value("${server.internal.ssl.keyStoreType:PKCS12}") + @Value("${server.internal.ssl.keyStoreType:${server.ssl.keyStoreType:PKCS12}}") private String keyStoreType; - @Value("${server.internal.ssl.keyPassword:password}") + @Value("${server.internal.ssl.keyPassword:${server.ssl.keyPassword:#{null}}}") private String keyPassword; - @Value("${server.internal.ssl.keyAlias:localhost}") + @Value("${server.internal.ssl.keyAlias:${server.ssl.keyAlias:#{null}}}") private String keyAlias; - @Value("${server.internal.ssl.trustStore:keystore/localhost/localhost.truststore.p12}") + @Value("${server.internal.ssl.trustStore:${server.ssl.trustStore:#{null}}}") private String trustStorePath; - @Value("${server.internal.ssl.trustStorePassword:password}") + @Value("${server.internal.ssl.trustStorePassword:${server.ssl.trustStorePassword:#{null}}}") private String trustStorePassword; - @Value("${server.internal.ssl.trustStoreType:PKCS12}") + @Value("${server.internal.ssl.trustStoreType:${server.ssl.trustStoreType:PKCS12}}") private String trustStoreType; + @Value("${server.internal.ssl.protocol:${server.ssl.protocol:TLSv1.2}}") + private String sslProtocol; + @Value("${server.internal.ssl.enabled-protocols:${apiml.httpclient.ssl.enabled-protocols:TLSv1.2,TLSv1.3}}") + private String supportedProtocols; @Value("${server.ssl.ciphers}") private String ciphers; @Value("${server.address}") @@ -77,12 +81,19 @@ public ServletWebServerFactory servletContainer(List private String getStorePath(String path) { if (SecurityUtils.isKeyring(path)) { - return path; + return SecurityUtils.formatKeyringUrl(path); } else { return new File(path).getAbsolutePath(); } } + private String getPassword(String path, String password) { + if (SecurityUtils.isKeyring(path) && password == null) { + return "password"; + } + return password; + } + private Connector createSslConnector() throws UnknownHostException { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); @@ -92,20 +103,21 @@ private Connector createSslConnector() throws UnknownHostException { connector.setScheme("https"); connector.setSecure(true); protocol.setSSLEnabled(true); - protocol.setSslEnabledProtocols("TLSv1.2"); + protocol.setSSLProtocol(sslProtocol); + protocol.setSslEnabledProtocols(supportedProtocols); protocol.setSSLHonorCipherOrder(true); protocol.setCiphers(ciphers); protocol.setClientAuth(clientAuth); protocol.setAddress(InetAddress.getByName(address)); protocol.setKeystoreFile(getStorePath(keyStorePath)); - protocol.setKeystorePass(keyStorePassword); + protocol.setKeystorePass(getPassword(keyStorePath, keyStorePassword)); protocol.setKeystoreType(keyStoreType); protocol.setTruststoreFile(getStorePath(trustStorePath)); - protocol.setTruststorePass(trustStorePassword); + protocol.setTruststorePass(getPassword(trustStorePath, trustStorePassword)); protocol.setTruststoreType(trustStoreType); protocol.setKeyAlias(keyAlias); - protocol.setKeyPass(keyPassword); + protocol.setKeyPass(getPassword(keyStorePath, keyPassword)); } else { connector.setScheme("http"); connector.setSecure(false); From 915c12d583e84b56b499bdbb2d2784058abc05de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Thu, 20 Nov 2025 13:54:48 +0100 Subject: [PATCH 21/45] extend for server address (internal vs. external) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- gateway-package/src/main/resources/bin/start.sh | 3 ++- .../org/zowe/apiml/gateway/config/TomcatConfiguration.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gateway-package/src/main/resources/bin/start.sh b/gateway-package/src/main/resources/bin/start.sh index 8ef7902b34..df4753c8b3 100755 --- a/gateway-package/src/main/resources/bin/start.sh +++ b/gateway-package/src/main/resources/bin/start.sh @@ -365,7 +365,7 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${GATEWAY_CODE} java \ -Dapiml.security.auth.passticket.customAuthHeader=${ZWE_configs_apiml_security_auth_passticket_customAuthHeader:-} \ -Dapiml.security.personalAccessToken.enabled=${ZWE_configs_apiml_security_personalAccessToken_enabled:-false} \ -Dapiml.zoweManifest=${ZWE_zowe_runtimeDirectory}/manifest.json \ - -Dserver.address=0.0.0.0 \ + -Dserver.address=${ZWE_configs_server_address:-0.0.0.0} \ -Dserver.maxConnectionsPerRoute=${ZWE_configs_server_maxConnectionsPerRoute:-100} \ -Dserver.maxTotalConnections=${ZWE_configs_server_maxTotalConnections:-1000} \ -Dserver.webSocket.maxIdleTimeout=${ZWE_configs_server_webSocket_maxIdleTimeout:-3600000} \ @@ -397,6 +397,7 @@ _BPX_JOBNAME=${ZWE_zowe_job_prefix}${GATEWAY_CODE} java \ -Dserver.internal.ssl.trustStore=${ZWE_configs_server_internal_ssl_certificate_truststore_file:-${truststore_location}} \ -Dserver.internal.ssl.trustStoreType=${ZWE_configs_server_internal_ssl_certificate_truststoretype:-${truststore_type}} \ -Dserver.internal.ssl.trustStorePassword=${ZWE_configs_server_internal_ssl_certificate_truststorepassword:-${truststore_pass}} \ + -Dserver.internal.address=${ZWE_configs_server_internal_address:-${ZWE_configs_server_address:-0.0.0.0}} \ -Dapiml.httpclient.conn-pool.requestConnectionTimeout=${ZWE_configs_apiml_gateway_httpclient_requestConnectionTimeout:-10000} \ -Dapiml.security.auth.zosmf.jwtAutoconfiguration=${ZWE_configs_apiml_security_auth_zosmf_jwtAutoconfiguration:-auto} \ -Dapiml.security.jwtInitializerTimeout=${ZWE_configs_apiml_security_jwtInitializerTimeout:-5} \ diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java index 9c91d0a388..da9c26f58f 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/config/TomcatConfiguration.java @@ -62,9 +62,9 @@ public class TomcatConfiguration { private String sslProtocol; @Value("${server.internal.ssl.enabled-protocols:${apiml.httpclient.ssl.enabled-protocols:TLSv1.2,TLSv1.3}}") private String supportedProtocols; - @Value("${server.ssl.ciphers}") + @Value("${server.internal.ssl.ciphers:${server.ssl.ciphers}}") private String ciphers; - @Value("${server.address}") + @Value("${server.internal.address:${server.address}}") private String address; @Bean From 8a07f22b4ca7175276e9308ab91776c3683123ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 15:12:11 +0100 Subject: [PATCH 22/45] Fix handling of unsupported caching service mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../apiml/caching/api/CachingController.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java b/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java index 2051377e39..81c954a80f 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/api/CachingController.java @@ -130,7 +130,13 @@ public ResponseEntity getAllMapItems(@PathVariable String mapKey, HttpSe try { return new ResponseEntity<>(storage.getAllMapItems(s, mapKey), HttpStatus.OK); } catch (Exception exception) { - return handleIncompatibleStorageMethod(exception, request.getRequestURL()); + if ( + (exception instanceof StorageException) && + Messages.INCOMPATIBLE_STORAGE_METHOD.getKey().equals(((StorageException) exception).getKey()) + ) { + return handleIncompatibleStorageMethod(exception, request.getRequestURL()); + } + return handleInternalError(exception, request.getRequestURL()); } } ).orElseGet(this::getUnauthorizedResponse); @@ -147,7 +153,13 @@ public ResponseEntity getAllMaps(HttpServletRequest request) { try { return new ResponseEntity<>(storage.getAllMaps(s), HttpStatus.OK); } catch (Exception exception) { - return handleIncompatibleStorageMethod(exception, request.getRequestURL()); + if ( + (exception instanceof StorageException) && + Messages.INCOMPATIBLE_STORAGE_METHOD.getKey().equals(((StorageException) exception).getKey()) + ) { + return handleIncompatibleStorageMethod(exception, request.getRequestURL()); + } + return handleInternalError(exception, request.getRequestURL()); } } ).orElseGet(this::getUnauthorizedResponse); From 1d6ba320a588dd3bb0c419be8403b9f9fabc7e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 15:12:32 +0100 Subject: [PATCH 23/45] fix org.infinispan.commons.marshall.MarshallingException: java.lang.NoSuchMethodException: org.zowe.apiml.caching.service.infinispan.storage.InfinispanStorage$$Lambda$2483/0x0000000000000000.writeReplace() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../infinispan/storage/InfinispanStorage.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java index 1e44474a5c..907b7c09e9 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/storage/InfinispanStorage.java @@ -99,10 +99,21 @@ public Map getAllMapItems(String serviceId, String mapKey) { @Override public Map> getAllMaps(String serviceId) { log.info("Reading all records from token cache for service {} ", serviceId); - // filter all maps which belong given service and remove the service name from key names. - return tokenCache.entrySet().stream().filter( - entry -> entry.getKey().startsWith(serviceId)) - .collect(Collectors.toMap(e -> e.getKey().substring(serviceId.length()), Map.Entry::getValue)); + + /** + * Original implementation with stream, collect and lambdas to read keys leads to serializing of lambdas, + * see org.infinispan.marshall.core.LambdaMarshaller#write(java.io.ObjectOutput, java.lang.Object). + * It is difficult to support and also slower (see exchanging lambdas between nodes). + */ + Map> result = new HashMap<>(); + for (String key : tokenCache.keySet()) { + if (!key.startsWith(serviceId)) continue; + + String newKey = key.substring(serviceId.length()); + result.put(newKey, tokenCache.get(key)); + } + + return result; } @Override @@ -228,4 +239,5 @@ private void completeJoin(CompletableFuture complete) { } } } + } From 9636c9b7988297e23c5f8120d9d584289df4bd9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 16:08:28 +0100 Subject: [PATCH 24/45] fix tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../apiml/caching/api/CachingControllerTest.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java b/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java index e078a6d17e..301fc2dd0d 100644 --- a/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java +++ b/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java @@ -387,12 +387,21 @@ void givenNoCertificateInformation_thenReturnUnauthorized() throws StorageExcept } @Test - void givenErrorReadingStorage_thenResponseBadRequest() throws StorageException { - when(mockStorage.getAllMapItems(any(), any())).thenThrow(new RuntimeException("error")); + void givenInvalidStorage_thenResponseBadRequest() throws StorageException { + when(mockStorage.getAllMapItems(any(), any())).thenThrow(new StorageException(Messages.INCOMPATIBLE_STORAGE_METHOD.getKey(), HttpStatus.BAD_REQUEST)); ResponseEntity response = underTest.getAllMapItems(any(), mockRequest); assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST)); } + + @Test + void givenGenericErrorReadingStorage_thenResponseInternalError() throws StorageException { + when(mockStorage.getAllMapItems(any(), any())).thenThrow(new RuntimeException("error")); + + ResponseEntity response = underTest.getAllMapItems(any(), mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + } @Nested From 3942b4b22193aa180d7c71567744f3cdcf113f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Tue, 9 Dec 2025 16:55:45 +0100 Subject: [PATCH 25/45] remove dependency IT > caching service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- integration-tests/build.gradle | 1 - .../apiml/integration/ha/CachingService.java | 38 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/integration-tests/build.gradle b/integration-tests/build.gradle index fd5a39196c..6bf20a20ab 100644 --- a/integration-tests/build.gradle +++ b/integration-tests/build.gradle @@ -36,7 +36,6 @@ dependencies { testImplementation libs.bcpkix; testImplementation project(':apiml-security-common') testImplementation project(':zaas-client') - testImplementation project(':caching-service') testImplementation libs.hamcrest testImplementation libs.awaitility diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 073a8bfcbf..525dc4cdf6 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -10,15 +10,20 @@ package org.zowe.apiml.integration.ha; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; import io.restassured.RestAssured; +import lombok.Data; +import lombok.RequiredArgsConstructor; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import org.zowe.apiml.caching.model.KeyValue; import org.zowe.apiml.util.categories.ChaoticHATest; import org.zowe.apiml.util.config.*; +import java.io.Serializable; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Random; import java.util.stream.Collectors; @@ -102,4 +107,35 @@ void testIt() { } + @RequiredArgsConstructor + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @Data + static class KeyValue implements Serializable { + + private final String key; + private final String value; + private String serviceId; + private final String created; + + public KeyValue(String key, String value) { + this.key = key; + this.value = value; + this.serviceId = ""; + this.created = currentTime(); + } + + private static String currentTime() { + return String.valueOf(new Date().getTime()); + } + + @JsonCreator + public KeyValue() { + key = ""; + value = ""; + serviceId = ""; + created = currentTime(); + } + + } + } From 4e986b2545ef03e3bf7a69bf9e8fe142321f8c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 10:47:12 +0100 Subject: [PATCH 26/45] draft of GA for IT and new keystore to support caching-service-3 host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .github/workflows/integration-tests.yml | 65 ++++++++++++++++++++++ keystore/docker/all-services.keystore.p12 | Bin 5709 -> 4638 bytes 2 files changed, 65 insertions(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d7a616a49a..652e563854 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1307,6 +1307,71 @@ jobs: - uses: ./.github/actions/teardown + CITestsCachingChaoticHA: + needs: PublishJibContainers + container: ubuntu:latest + runs-on: ubuntu-latest + timeout-minutes: 15 + + services: + caching-service: + image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} + env: + MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true + MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown + STORAGE_MODE: infinispan + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" + JGROUPS_BIND_PORT: 7600 + JGROUPS_BIND_ADDRESS: caching-service + JGROUPS_KEYEXCHANGE_PORT: 7602 + APIML_SERVICE_HOSTNAME: caching-service + caching-service-2: + image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} + caching-service-3: + image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} + mock-services: + image: ghcr.io/balhar-jakub/mock-services:${{ github.run_id }}-${{ github.run_number }} + discovery-service: + image: ghcr.io/balhar-jakub/discovery-service:${{ github.run_id }}-${{ github.run_number }} + volumes: + - /api-defs:/api-defs + env: + APIML_DISCOVERY_ALLPEERSURLS: https://discovery-service:10011/eureka,https://discovery-service-2:10011/eureka + gateway-service: + image: ghcr.io/balhar-jakub/gateway-service:${{ github.run_id }}-${{ github.run_number }} + env: + APIML_SERVICE_DISCOVERYSERVICEURLS: https://discovery-service:10011/eureka/,https://discovery-service-2:10011/eureka/ + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - uses: ./.github/actions/setup + + - name: Run Caching Chaotic HA Tests + run: > + ./gradlew :integration-tests:runChaoticHATests --tests org.zowe.apiml.integration.ha.CachingService + --info -Denvironment.config=-ha -Denvironment.offPlatform=true -DcloudGateway.enabled=false + -Partifactory_user=$ARTIFACTORY_USERNAME -Partifactory_password=$ARTIFACTORY_PASSWORD + env: + ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} + ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} + + - name: Correct Permisions + run: | + chmod 755 -R .gradle + # Coverage results are not stored in this job as it would not provide much additional data + - name: Store results + uses: actions/upload-artifact@v4 + if: always() + with: + name: CITestsWebSocketChaoticHA-${{ env.JOB_ID }} + path: | + integration-tests/build/reports/** + results/** + + - uses: ./.github/actions/teardown + CITestsWithInfinispan: needs: PublishJibContainers runs-on: ubuntu-latest diff --git a/keystore/docker/all-services.keystore.p12 b/keystore/docker/all-services.keystore.p12 index 96e547fa4f3202b8be5d46d906c4a3c2eff4ad11..1eee767e03cf76b87f1257012bd4dd1097c0f62b 100644 GIT binary patch literal 4638 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 C#eJaw literal 5709 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 From 7f2d096cfdcfc593428fe4ce6022de57d58984d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 13:24:05 +0100 Subject: [PATCH 27/45] waiting to caching services are up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../apiml/integration/ha/CachingService.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 525dc4cdf6..4065f3583b 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -15,11 +15,14 @@ import io.restassured.RestAssured; import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.hamcrest.Matchers; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.zowe.apiml.util.categories.ChaoticHATest; import org.zowe.apiml.util.config.*; +import org.zowe.apiml.util.requests.Endpoints; import java.io.Serializable; import java.util.Arrays; @@ -30,12 +33,16 @@ import static io.restassured.RestAssured.given; import static io.restassured.http.ContentType.JSON; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.apache.http.HttpStatus.SC_OK; +import static org.awaitility.Awaitility.await; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.core.Is.is; import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.zowe.apiml.util.config.ConfigReader.environmentConfiguration; +@Slf4j @ChaoticHATest @TestInstance(TestInstance.Lifecycle. PER_CLASS) public class CachingService { @@ -49,6 +56,36 @@ public class CachingService { private Credentials credentials; private List baseUrls; + private boolean isUp(int index) { + try { + String url = String.format("%s/cachingservice%s", baseUrls.get(index), Endpoints.HEALTH); + log.info("Check if {}. Caching Service is up: {}", index, url); + + given() + .contentType(JSON) + .auth() + .basic(credentials.getUser(), credentials.getPassword()) + .when() + .get(url) + .then() + .statusCode(200) + .body("status", Matchers.is("UP")); + return true; + } catch (AssertionError e) { + log.info("Caching service is down", e); + return false; + } + } + + private boolean isUp() { + for (int i = 0; i < baseUrls.size(); i++) { + if (!isUp(i)) { + return false; + } + } + return true; + } + @BeforeAll void setUp() throws Exception { RestAssured.useRelaxedHTTPSValidation(); @@ -64,6 +101,12 @@ void setUp() throws Exception { .map(host -> String.format("%s://%s:%d", cachingServiceConfiguration.getScheme(), host, cachingServiceConfiguration.getPort())) .collect(Collectors.toList()); credentials = ConfigReader.environmentConfiguration().getCredentials(); + + await() + .atMost(10, MINUTES) + .pollDelay(0, SECONDS) + .pollInterval(10, SECONDS) + .until(this::isUp); } @Test From 217c3ac7d1863674e023e963d9bf5e6d5b0ba9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 13:36:12 +0100 Subject: [PATCH 28/45] add log messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../org/zowe/apiml/integration/ha/CachingService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 4065f3583b..6e13daad3b 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -59,7 +59,7 @@ public class CachingService { private boolean isUp(int index) { try { String url = String.format("%s/cachingservice%s", baseUrls.get(index), Endpoints.HEALTH); - log.info("Check if {}. Caching Service is up: {}", index, url); + log.info("Check if {}. Caching Service is up: {}", index + 1, url); given() .contentType(JSON) @@ -110,7 +110,8 @@ void setUp() throws Exception { } @Test - void testIt() { + void givenMultipleInstances_whenShareAValue_thenShutdownDoesntChangeTheState() { + log.info("Set value on the first instance"); given() .config(SslContext.clientCertApiml) .header("X-Certificate-DistinguishedName", SERVICE) @@ -124,7 +125,7 @@ void testIt() { int instances = baseUrls.size(); for (int i = -1; i < instances - 1; i++) { if (i >= 0) { - // kill caching service + log.info("Kill {}. instance of caching service", i + 1); given() .config(SslContext.clientCertApiml) .contentType(JSON) @@ -136,7 +137,7 @@ void testIt() { } for (int j = i + 1; j < instances; j++) { - // check if the value is accessible + log.info("Check if the value is accessible {}. instance", i + 1); given() .config(SslContext.clientCertApiml) .header("X-Certificate-DistinguishedName", SERVICE) From 24b2879a528d499535c184a13936f7770f56db50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 14:10:22 +0100 Subject: [PATCH 29/45] IT fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .github/workflows/integration-tests.yml | 22 +++++++++++++++---- .../apiml/integration/ha/CachingService.java | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 96b780cef5..1d95cf725e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1331,20 +1331,34 @@ jobs: APIML_SERVICE_HOSTNAME: caching-service caching-service-2: image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} + env: + MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true + MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown + STORAGE_MODE: infinispan + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" + JGROUPS_BIND_PORT: 7600 + JGROUPS_BIND_ADDRESS: caching-service-2 + JGROUPS_KEYEXCHANGE_PORT: 7602 + APIML_SERVICE_HOSTNAME: caching-service-2 caching-service-3: image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} + env: + MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true + MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown + STORAGE_MODE: infinispan + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" + JGROUPS_BIND_PORT: 7600 + JGROUPS_BIND_ADDRESS: caching-service-3 + JGROUPS_KEYEXCHANGE_PORT: 7602 + APIML_SERVICE_HOSTNAME: caching-service-3 mock-services: image: ghcr.io/balhar-jakub/mock-services:${{ github.run_id }}-${{ github.run_number }} discovery-service: image: ghcr.io/balhar-jakub/discovery-service:${{ github.run_id }}-${{ github.run_number }} volumes: - /api-defs:/api-defs - env: - APIML_DISCOVERY_ALLPEERSURLS: https://discovery-service:10011/eureka,https://discovery-service-2:10011/eureka gateway-service: image: ghcr.io/balhar-jakub/gateway-service:${{ github.run_id }}-${{ github.run_number }} - env: - APIML_SERVICE_DISCOVERYSERVICEURLS: https://discovery-service:10011/eureka/,https://discovery-service-2:10011/eureka/ steps: - uses: actions/checkout@v4 with: diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 6e13daad3b..aa9e06fdbb 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -137,7 +137,7 @@ void givenMultipleInstances_whenShareAValue_thenShutdownDoesntChangeTheState() { } for (int j = i + 1; j < instances; j++) { - log.info("Check if the value is accessible {}. instance", i + 1); + log.info("Check if the value is accessible {}. instance", j + 1); given() .config(SslContext.clientCertApiml) .header("X-Certificate-DistinguishedName", SERVICE) From 0fb850b9909acd3b9f60ed5eebac8417a359eecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 14:41:19 +0100 Subject: [PATCH 30/45] update infinispan ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .github/workflows/integration-tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 1d95cf725e..c10ecc811e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1324,10 +1324,10 @@ jobs: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown STORAGE_MODE: infinispan - CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" - JGROUPS_BIND_PORT: 7600 + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" + JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service - JGROUPS_KEYEXCHANGE_PORT: 7602 + JGROUPS_KEYEXCHANGE_PORT: 7118 APIML_SERVICE_HOSTNAME: caching-service caching-service-2: image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} @@ -1335,10 +1335,10 @@ jobs: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown STORAGE_MODE: infinispan - CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" - JGROUPS_BIND_PORT: 7600 + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" + JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service-2 - JGROUPS_KEYEXCHANGE_PORT: 7602 + JGROUPS_KEYEXCHANGE_PORT: 7118 APIML_SERVICE_HOSTNAME: caching-service-2 caching-service-3: image: ghcr.io/balhar-jakub/caching-service:${{ github.run_id }}-${{ github.run_number }} @@ -1346,10 +1346,10 @@ jobs: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown STORAGE_MODE: infinispan - CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7600],caching-service-2[7600],caching-service-3[7600]" - JGROUPS_BIND_PORT: 7600 + CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" + JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service-3 - JGROUPS_KEYEXCHANGE_PORT: 7602 + JGROUPS_KEYEXCHANGE_PORT: 7118 APIML_SERVICE_HOSTNAME: caching-service-3 mock-services: image: ghcr.io/balhar-jakub/mock-services:${{ github.run_id }}-${{ github.run_number }} From 40e9db9a289157b68d6b9967697ba40b6ee3e21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 14:58:41 +0100 Subject: [PATCH 31/45] fix test to use infinispan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .github/workflows/integration-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index c10ecc811e..b1980c9122 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1323,7 +1323,7 @@ jobs: env: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown - STORAGE_MODE: infinispan + CACHING_STORAGE_MODE: infinispan CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service @@ -1334,7 +1334,7 @@ jobs: env: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown - STORAGE_MODE: infinispan + CACHING_STORAGE_MODE: infinispan CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service-2 @@ -1345,7 +1345,7 @@ jobs: env: MANAGEMENT_ENDPOINT_SHUTDOWN_ENABLED: true MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,hystrixstream,shutdown - STORAGE_MODE: infinispan + CACHING_STORAGE_MODE: infinispan CACHING_STORAGE_INFINISPAN_INITIALHOSTS: "caching-service[7098],caching-service-2[7098],caching-service-3[7098]" JGROUPS_BIND_PORT: 7098 JGROUPS_BIND_ADDRESS: caching-service-3 From 6c5a8018a180d244808bfc3331d2d569a6234044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 15:18:25 +0100 Subject: [PATCH 32/45] debugging - wait for JGroups for another 2mins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../org/zowe/apiml/integration/ha/CachingService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index aa9e06fdbb..881ca5bf22 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -107,6 +107,14 @@ void setUp() throws Exception { .pollDelay(0, SECONDS) .pollInterval(10, SECONDS) .until(this::isUp); + + log.info("Waiting for joining into a cluster"); + await() + .atMost(2, MINUTES) + .pollDelay(0, SECONDS) + .pollInterval(2, MINUTES) + .until(() -> true); + log.info("Ready to test"); } @Test From d752643c8c24f8f124579d8dad99a85831592ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 15:27:44 +0100 Subject: [PATCH 33/45] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../test/java/org/zowe/apiml/integration/ha/CachingService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 881ca5bf22..82a032e810 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -111,7 +111,7 @@ void setUp() throws Exception { log.info("Waiting for joining into a cluster"); await() .atMost(2, MINUTES) - .pollDelay(0, SECONDS) + .pollDelay(2, MINUTES) .pollInterval(2, MINUTES) .until(() -> true); log.info("Ready to test"); From 82067c8546c79b1fbc4bd234bfe6a6c84e83983b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 15:46:52 +0100 Subject: [PATCH 34/45] fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .github/workflows/integration-tests.yml | 2 +- .../test/java/org/zowe/apiml/integration/ha/CachingService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b1980c9122..d6323fd8df 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1383,7 +1383,7 @@ jobs: uses: actions/upload-artifact@v4 if: always() with: - name: CITestsWebSocketChaoticHA-${{ env.JOB_ID }} + name: CITestsCachingChaoticHA-${{ env.JOB_ID }} path: | integration-tests/build/reports/** results/** diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 82a032e810..9e61cd2f61 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -110,7 +110,7 @@ void setUp() throws Exception { log.info("Waiting for joining into a cluster"); await() - .atMost(2, MINUTES) + .atMost(10, MINUTES) .pollDelay(2, MINUTES) .pollInterval(2, MINUTES) .until(() -> true); From b565a8108ed15b27e29ddd473fd56bf45bd11675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 17:13:56 +0100 Subject: [PATCH 35/45] remove unused values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../caching/service/infinispan/config/InfinispanConfig.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 171c1a8709..3983038b19 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -62,12 +62,6 @@ public class InfinispanConfig implements InitializingBean { @Value("${caching.storage.infinispan.initialHosts}") private String initialHosts; - @Value("${caching.storage.infinispan.persistence.dataLocation}") - private String dataLocation; - - @Value("${caching.storage.infinispan.persistence.indexLocation:index}") - private String indexLocation; - @Value("${server.ssl.keyStoreType}") private String keyStoreType; From acd42dca02f15d8220bdb302c59da36798db0892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 17:14:15 +0100 Subject: [PATCH 36/45] update certificate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- keystore/docker/all-services.keystore.cer | 55 ++++++++++++----------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/keystore/docker/all-services.keystore.cer b/keystore/docker/all-services.keystore.cer index f57a69a825..bdb1270f5d 100644 --- a/keystore/docker/all-services.keystore.cer +++ b/keystore/docker/all-services.keystore.cer @@ -1,32 +1,33 @@ -----BEGIN CERTIFICATE----- -MIIFlzCCBH+gAwIBAgIUJ6g/GJD3j4lB+bETn26Eeon+8A4wDQYJKoZIhvcNAQEL +MIIFyjCCBLKgAwIBAgIUIOG3WV7VbkbX0KIy4NTraWqn6p0wDQYJKoZIhvcNAQEL BQAwgZ4xCzAJBgNVBAYTAkNaMQ8wDQYDVQQIEwZQcmFndWUxDzANBgNVBAcTBlBy YWd1ZTEUMBIGA1UEChMLWm93ZSBTYW1wbGUxHDAaBgNVBAsTE0FQSSBNZWRpYXRp b24gTGF5ZXIxOTA3BgNVBAMTMFpvd2UgRGV2ZWxvcG1lbnQgSW5zdGFuY2VzIENl -cnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjEyMTUxMjE1MzJaFw0yNzEyMTQxMjE1 -MzJaMHwxCzAJBgNVBAYTAkNaMQ8wDQYDVQQIDAZQcmFndWUxDzANBgNVBAcMBlBy -YWd1ZTEUMBIGA1UECgwLWm93ZSBTYW1wbGUxHDAaBgNVBAsME0FQSSBNZWRpYXRp -b24gTGF5ZXIxFzAVBgNVBAMMDlpvd2UgQ29tcG9uZW50MIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAsrNR9CgPcNrLDrE0B5hAjA+pgEPJ73olU4Chr5uY -9w6yuEDy08I+W4Bitu/ScI8qbkJB7hITwgM43ZQU23QEqP1luW8msRvYaUzZcuyw -gsGKTjtUmPi1BEQmmo6MFGVwjpdGBNJqbCKuMHVi8G8Xc9CrevCUQp9Pw4SOu4bY -6FZG8nbzYoTgHBXHwvccv8Ov07lLv1ohk3BdHkDjtoEgSfFtJrCW2Jkk/4MYpYFR -t2WKjTdOQLSpGptSS2EC8M6UmpZTYyLhDprP0EAdT/IcKg7/QR4/TbSo7soY0Dx1 -5jFZqg/2mvqCywAtx8vPvhBNzPVOVfL+V46iw13pKm6MnQIDAQABo4IB7DCCAegw -HQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMIIBhQYDVR0RBIIBfDCCAXiC -CWxvY2FsaG9zdIIJMTI3LjAuMC4xgg9nYXRld2F5LXNlcnZpY2WCEWdhdGV3YXkt -c2VydmljZS0yghRhcGktY2F0YWxvZy1zZXJ2aWNlc4IWYXBpLWNhdGFsb2ctc2Vy -dmljZXMtMoIPY2FjaGluZy1zZXJ2aWNlghFjYWNoaW5nLXNlcnZpY2UtMoIRZGlz -Y292ZXJ5LXNlcnZpY2WCE2Rpc2NvdmVyeS1zZXJ2aWNlLTKCE2Rpc2NvdmVyYWJs -ZS1jbGllbnSCFWRpc2NvdmVyYWJsZS1jbGllbnQtMYIVZGlzY292ZXJhYmxlLWNs -aWVudC0yghVkaXNjb3ZlcmFibGUtY2xpZW50LTOCFWRpc2NvdmVyYWJsZS1jbGll -bnQtNIINbW9jay1zZXJ2aWNlc4IPbW9jay1zZXJ2aWNlcy0ygg9tZXRyaWNzLXNl -cnZpY2WCEW1ldHJpY3Mtc2VydmljZS0ygg1yZXZlcnNlLXByb3h5MB0GA1UdDgQW -BBQiM604apFGByEW0V0q+C9KnvbfpzAfBgNVHSMEGDAWgBQkaS422MefPS4tRH1i -sBpkMYiwNjANBgkqhkiG9w0BAQsFAAOCAQEAZApmzT8KLZO6UeP93quH6/JNNYxw -MHWcww4ulCDiRkC6Lg7Td+QYn6ttg60GbEZbw1NszfRNCYh6yz5MSjC314sw+AVO -PaVjNQDdxAyU5xZ57yvmJs5pPub2Z8WD42SXvBoWB1wH3ErUs7XfznhjpTVokeZK -DMUUAfA0a/A1ZuvLWcK5EOHbi5SDqZ5ieI5qnfePVhDQHsS1El90GLXq0B1X+UXf -G4RKG6FV7+zMFig/w36qyCcWm7NMvqEb6LfeIdZEgTWYGPZeYYHbHjd8LCU0TSRg -+R1wYQmT3Kpi/63V7VfHYywt+j5Zofpk17jslRfv18KoW9Yo0KMK3fuixA== +cnRpZmljYXRlIEF1dGhvcml0eTAeFw0yNTEyMTAwOTI1MzdaFw0zMDEyMDkwOTI1 +MzdaMGwxCzAJBgNVBAYTAkNaMRAwDgYDVQQIDAdDemVjaGlhMQ8wDQYDVQQHDAZQ +cmFndWUxETAPBgNVBAoMCEJyb2FkY29tMQwwCgYDVQQLDANNU0QxGTAXBgNVBAMM +ECdab3dlIENvbXBvbmVudCcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC24tPOjwNlLZV0gRay1YhNe4X7rs0n4Oo2HqvbGkV3mrIK98ADXTuLzr9JFrsL +KKf64aykt0jHJtZdUXsgoQQ4odtGemtWlSaJjtAAHtls+6dxyZWDltuyVH9Nrwr3 +kwr3ESOyXC3LEOhwkpUGMMdK5wMpbXBeaH9zttMTOizKQpv9wntMB9wJQKjxL7oC +Xez+1nCnH+zkQPwxNBw5bA/PAEF2eVXi9Bm4vaRdalsJLczTcXc43SC88IgfpCLd +pMkAoWRVnr06MvgxyewVgjHewhmL7ZLBimbDBeWz2i7fcOhkPc3E6O5W0JSJ1J+a +D5kkHE72h3koaMq/TevPeAafAgMBAAGjggIvMIICKzAdBgNVHSUEFjAUBggrBgEF +BQcDAgYIKwYBBQUHAwEwggHIBgNVHREEggG/MIIBu4IJbG9jYWxob3N0ggkxMjcu +MC4wLjGCD2dhdGV3YXktc2VydmljZYIRZ2F0ZXdheS1zZXJ2aWNlLTKCFGFwaS1j +YXRhbG9nLXNlcnZpY2VzghZhcGktY2F0YWxvZy1zZXJ2aWNlcy0ygg9jYWNoaW5n +LXNlcnZpY2WCEWNhY2hpbmctc2VydmljZS0yghFjYWNoaW5nLXNlcnZpY2UtM4IR +ZGlzY292ZXJ5LXNlcnZpY2WCE2Rpc2NvdmVyeS1zZXJ2aWNlLTKCE2Rpc2NvdmVy +YWJsZS1jbGllbnSCFWRpc2NvdmVyYWJsZS1jbGllbnQtMYIVZGlzY292ZXJhYmxl +LWNsaWVudC0yghVkaXNjb3ZlcmFibGUtY2xpZW50LTOCFWRpc2NvdmVyYWJsZS1j +bGllbnQtNIINbW9jay1zZXJ2aWNlc4IPbW9jay1zZXJ2aWNlcy0ygg9tZXRyaWNz +LXNlcnZpY2WCEW1ldHJpY3Mtc2VydmljZS0ygg1yZXZlcnNlLXByb3h5ghVjbG91 +ZC1nYXRld2F5LXNlcnZpY2WCF2Nsb3VkLWdhdGV3YXktc2VydmljZS0yMB0GA1Ud +DgQWBBRomE05vqsfKS5pYQ71YoVSixeU2TAfBgNVHSMEGDAWgBQkaS422MefPS4t +RH1isBpkMYiwNjANBgkqhkiG9w0BAQsFAAOCAQEAO5wB8COl45U7Cq6saaW3/xqm +od1Dx068ziaDQTj1CL1A5jJ/JTUMNWEHeBBfPFGvKBq1IqpnNMR96+C2mIt9LWck +49khLzWvcWVKLg+9IJixceQrn43ZziD/p11EHVDz1KLn8Hn1ElnDavPL2hBxO7uE +RdZCVY4SFbB3bc2OsK7qmal+SQFRrEpawaF4GXWCOGp2uZhnytBQEaqxQE9v24pj +qoYeSwA6/IrF+C5mW8HbdYIBn9Te8joGJ5xMW1XTtumxxOJytpLy/4zRwxKoxJLA +eXhWn/1S7l/6jWT9+df+8wfiFywJOEGqyawFB5ysWAaQDpl6nkTyVjDLwJq42w== -----END CERTIFICATE----- From d7de2b018f3eb3f1313b5cc941f34aa647b39886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Wed, 10 Dec 2025 17:27:40 +0100 Subject: [PATCH 37/45] update all-services.keystore.p12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- keystore/docker/all-services.keystore.p12 | Bin 4638 -> 5854 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/keystore/docker/all-services.keystore.p12 b/keystore/docker/all-services.keystore.p12 index 1eee767e03cf76b87f1257012bd4dd1097c0f62b..6424a833f6e439a35d8ad4279163aaed9e74f8c1 100644 GIT binary patch delta 4365 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 H0s;sCtFczL delta 3139 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 d1QZ*7U?^-0O^!|K{11t9QbG5nw!H!Z2msN5 Date: Wed, 10 Dec 2025 17:47:22 +0100 Subject: [PATCH 38/45] test clean-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../org/zowe/apiml/integration/ha/CachingService.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 9e61cd2f61..aa9e06fdbb 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -107,14 +107,6 @@ void setUp() throws Exception { .pollDelay(0, SECONDS) .pollInterval(10, SECONDS) .until(this::isUp); - - log.info("Waiting for joining into a cluster"); - await() - .atMost(10, MINUTES) - .pollDelay(2, MINUTES) - .pollInterval(2, MINUTES) - .until(() -> true); - log.info("Ready to test"); } @Test From c7466525c1b1dabd19d5d57bd9493689efce7829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Thu, 11 Dec 2025 12:06:22 +0100 Subject: [PATCH 39/45] fix usage of truststore by caching service (key exchange) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../infinispan/config/InfinispanConfig.java | 25 ++++++++++++++++++ .../src/main/resources/infinispan.xml | 3 +++ keystore/docker/all-services.keystore.p12 | Bin 5854 -> 4638 bytes 3 files changed, 28 insertions(+) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 3983038b19..128a7ff067 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -58,6 +58,9 @@ public class InfinispanConfig implements InitializingBean { private static final String SERVER_SSL_KEY_STORE_TYPE = "server.ssl.keyStoreType"; private static final String SERVER_SSL_KEY_STORE = "server.ssl.keyStore"; private static final String SERVER_SSL_KEY_STORE_PASSWORD = "server.ssl.keyStorePassword"; + private static final String SERVER_SSL_TRUST_STORE_TYPE = "server.ssl.trustStoreType"; + private static final String SERVER_SSL_TRUST_STORE = "server.ssl.trustStore"; + private static final String SERVER_SSL_TRUST_STORE_PASSWORD = "server.ssl.trustStorePassword"; @Value("${caching.storage.infinispan.initialHosts}") private String initialHosts; @@ -71,6 +74,15 @@ public class InfinispanConfig implements InitializingBean { @Value("${server.ssl.keyStorePassword}") private String keyStorePass; + @Value("${server.ssl.trustStoreType}") + private String trustStoreType; + + @Value("${server.ssl.trustStore}") + private String trustStore; + + @Value("${server.ssl.trustStorePassword}") + private String trustStorePass; + @Value("${jgroups.bind.port}") private String port; @@ -99,6 +111,10 @@ void updateKeyring() { keyStore = formatKeyringUrl(keyStore); if (StringUtils.isBlank(keyStorePass)) keyStorePass = KEYRING_PASSWORD; } + if (isKeyring(trustStore)) { + trustStore = formatKeyringUrl(trustStore); + if (StringUtils.isBlank(trustStorePass)) trustStorePass = KEYRING_PASSWORD; + } } static String getRootFolder() { @@ -127,11 +143,17 @@ synchronized DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { Optional oldKeyStoreType = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE_TYPE")); Optional oldKeyStore = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE")); Optional oldKeyStorePassword = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE_PASSWORD")); + Optional oldTrustStoreType = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE_TYPE")); + Optional oldTrustStore = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE")); + Optional oldTrustStorePassword = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE_PASSWORD")); if (!isServerAttlsEnabled) { System.setProperty(SERVER_SSL_KEY_STORE_TYPE, keyStoreType); System.setProperty(SERVER_SSL_KEY_STORE, keyStore); System.setProperty(SERVER_SSL_KEY_STORE_PASSWORD, keyStorePass); + System.setProperty(SERVER_SSL_TRUST_STORE_TYPE, trustStoreType); + System.setProperty(SERVER_SSL_TRUST_STORE, trustStore); + System.setProperty(SERVER_SSL_TRUST_STORE_PASSWORD, trustStorePass); } ConfigurationBuilderHolder holder; @@ -163,6 +185,9 @@ synchronized DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { oldKeyStoreType.ifPresent(keystoreType -> System.setProperty(SERVER_SSL_KEY_STORE_TYPE, keystoreType)); oldKeyStore.ifPresent(keystore -> System.setProperty(SERVER_SSL_KEY_STORE, keystore)); oldKeyStorePassword.ifPresent(keystorePassword -> System.setProperty(SERVER_SSL_KEY_STORE_PASSWORD, keystorePassword)); + oldTrustStoreType.ifPresent(trueststoreType -> System.setProperty(SERVER_SSL_TRUST_STORE_TYPE, trueststoreType)); + oldTrustStore.ifPresent(truststore -> System.setProperty(SERVER_SSL_TRUST_STORE, truststore)); + oldTrustStorePassword.ifPresent(truststorePassword -> System.setProperty(SERVER_SSL_TRUST_STORE_PASSWORD, truststorePassword)); return cacheManager; } diff --git a/caching-service/src/main/resources/infinispan.xml b/caching-service/src/main/resources/infinispan.xml index d80c07d6b6..b4cab80c31 100644 --- a/caching-service/src/main/resources/infinispan.xml +++ b/caching-service/src/main/resources/infinispan.xml @@ -26,6 +26,9 @@ diff --git a/keystore/docker/all-services.keystore.p12 b/keystore/docker/all-services.keystore.p12 index 6424a833f6e439a35d8ad4279163aaed9e74f8c1..114f9648acba65d1fc87831595b56149c5a04080 100644 GIT binary patch delta 3139 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 delta 4365 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 H0s;sCtFczL From 6ead3cc9bfa98fe695ddb2cc462f0263d66114c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Thu, 11 Dec 2025 17:38:27 +0100 Subject: [PATCH 40/45] code coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../caching/api/CachingControllerTest.java | 65 ++++++++++++++++++- .../token/ApimlAccessTokenProvider.java | 2 +- .../cache/CachingServiceClientTest.java | 34 ++++++++-- .../token/ApimlAccessTokenProviderTest.java | 27 +++++++- 4 files changed, 118 insertions(+), 10 deletions(-) diff --git a/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java b/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java index 301fc2dd0d..f2ab7720af 100644 --- a/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java +++ b/caching-service/src/test/java/org/zowe/apiml/caching/api/CachingControllerTest.java @@ -27,7 +27,8 @@ import org.zowe.apiml.message.yaml.YamlMessageService; import javax.servlet.http.HttpServletRequest; -import java.util.*; +import java.util.HashMap; +import java.util.Map; import java.util.stream.Stream; import static org.hamcrest.MatcherAssert.assertThat; @@ -426,4 +427,66 @@ void givenInCorrectRequest_thenReturn500() throws StorageException { assertThat(responseScopesEviction.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); } } + + @Nested + class WhenGetAll { + + @Nested + class MapItems { + + @Test + void givenWrongStorage_whenGetAllMapItems_thenReturn400() { + Exception storageException = new StorageException(Messages.INCOMPATIBLE_STORAGE_METHOD.getKey(), Messages.INCOMPATIBLE_STORAGE_METHOD.getStatus()); + doThrow(storageException).when(mockStorage).getAllMapItems(any(), any()); + ResponseEntity response = underTest.getAllMapItems(MAP_KEY, mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST)); + } + + @Test + void givenUnexpectedError_whenGetAllMapItems_thenReturn500() { + doThrow(new RuntimeException("unexpected")).when(mockStorage).getAllMapItems(any(), any()); + ResponseEntity response = underTest.getAllMapItems(MAP_KEY, mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + + @Test + void givenUOtherStorageException_whenGetAllMapItems_thenReturn500() { + Exception storageException = new StorageException(Messages.DUPLICATE_KEY.getKey(), Messages.DUPLICATE_KEY.getStatus()); + doThrow(storageException).when(mockStorage).getAllMapItems(any(), any()); + ResponseEntity response = underTest.getAllMapItems(MAP_KEY, mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + + } + + @Nested + class Maps { + + @Test + void givenWrongStorage_whenGetAllMapItems_thenReturn400() { + Exception storageException = new StorageException(Messages.INCOMPATIBLE_STORAGE_METHOD.getKey(), Messages.INCOMPATIBLE_STORAGE_METHOD.getStatus()); + doThrow(storageException).when(mockStorage).getAllMaps(any()); + ResponseEntity response = underTest.getAllMaps(mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST)); + } + + @Test + void givenUnexpectedError_whenGetAllMapItems_thenReturn500() { + doThrow(new RuntimeException("unexpected")).when(mockStorage).getAllMaps(any()); + ResponseEntity response = underTest.getAllMaps(mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + + @Test + void givenUOtherStorageException_whenGetAllMapItems_thenReturn500() { + Exception storageException = new StorageException(Messages.DUPLICATE_KEY.getKey(), Messages.DUPLICATE_KEY.getStatus()); + doThrow(storageException).when(mockStorage).getAllMaps(any()); + ResponseEntity response = underTest.getAllMaps(mockRequest); + assertThat(response.getStatusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR)); + } + + } + + } + } diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java index 569a8c8db8..0361f172e8 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProvider.java @@ -150,7 +150,7 @@ public String getHash(String token) throws CachingServiceClientException { return getSecurePassword(token, getSalt()); } - private String initializeSalt() throws CachingServiceClientException { + String initializeSalt() throws CachingServiceClientException { String localSalt; try { CachingServiceClient.KeyValue keyValue = cachingServiceClient.read("salt"); diff --git a/gateway-service/src/test/java/org/zowe/apiml/gateway/cache/CachingServiceClientTest.java b/gateway-service/src/test/java/org/zowe/apiml/gateway/cache/CachingServiceClientTest.java index 71f80e21be..66865e4c22 100644 --- a/gateway-service/src/test/java/org/zowe/apiml/gateway/cache/CachingServiceClientTest.java +++ b/gateway-service/src/test/java/org/zowe/apiml/gateway/cache/CachingServiceClientTest.java @@ -16,14 +16,13 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.zowe.apiml.models.AccessTokenContainer; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -100,10 +99,35 @@ void readWithoutProblem() throws CachingServiceClientException { } @Test - void readWithExceptonFromRestTemplateThrowsDefined() { + void readWithExceptionFromRestTemplateThrowsDefined() { doThrow(new RestClientException("oops")).when(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class)); assertThrows(CachingServiceClientException.class, () -> underTest.read(keyToRead)); } + + @Test + void ioException() { + RestClientException ioException = new RestClientException("io"); + doThrow(ioException).when(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(CachingServiceClient.KeyValue.class)); + CachingServiceClientException e = assertThrows(CachingServiceClientException.class, () -> underTest.read(keyToRead)); + assertSame(e.getCause(), ioException); + } + + @Test + void notFound() { + doThrow(HttpClientErrorException.create("record not found", HttpStatus.NOT_FOUND, "notFound", new HttpHeaders(), new byte[0], StandardCharsets.UTF_8)) + .when(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(CachingServiceClient.KeyValue.class)); + CachingServiceClientException e = assertThrows(CachingServiceClientException.class, () -> underTest.read(keyToRead)); + assertNull(e.getCause()); + } + + @Test + void noAvailable() { + Exception responseException = HttpClientErrorException.create("service not available", HttpStatus.SERVICE_UNAVAILABLE, "503", new HttpHeaders(), new byte[0], StandardCharsets.UTF_8); + doThrow(responseException).when(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(CachingServiceClient.KeyValue.class)); + CachingServiceClientException e = assertThrows(CachingServiceClientException.class, () -> underTest.read(keyToRead)); + assertSame(e.getCause(), responseException); + } + } @Nested diff --git a/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java b/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java index 1a0659433d..3eccfcd6dc 100644 --- a/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java +++ b/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java @@ -25,13 +25,12 @@ import org.zowe.apiml.models.AccessTokenContainer; import org.zowe.apiml.security.common.token.QueryResponse; +import java.io.IOException; import java.util.*; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; class ApimlAccessTokenProviderTest { @@ -223,4 +222,26 @@ static String createTestToken(String username, Map claims) { .addClaims(claims).compact(); } + @Nested + class SaltInitialization { + + @Test + void givenUnexpectedError_whenReadSalt_thenThrowIt() { + Exception unexpectedError = new CachingServiceClientException("unexpected error", new IOException("e.g. timeout")); + doThrow(unexpectedError).when(cachingServiceClient).read("salt"); + Exception thrownException = assertThrows(CachingServiceClientException.class, accessTokenProvider::initializeSalt); + assertSame(unexpectedError, thrownException); + } + + @Test + void givenNoSaltInCache_whenInitializing_thenCreateNewOne() { + byte[] salt = "salt".getBytes(); + Exception noRecordException = new CachingServiceClientException("no record"); + doThrow(noRecordException).when(cachingServiceClient).read("salt"); + assertEquals(new String(salt), accessTokenProvider.initializeSalt()); + verify(cachingServiceClient, times(1)).create(any()); + } + + } + } From 1046d1df793581d4e15ab87059fbeb68ec27b14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Thu, 11 Dec 2025 17:50:57 +0100 Subject: [PATCH 41/45] fix the initialization part (java.net.UnknownHostException: caching-service: Temporary failure in name resolution) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../java/org/zowe/apiml/integration/ha/CachingService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index aa9e06fdbb..60c9175154 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -71,8 +71,8 @@ private boolean isUp(int index) { .statusCode(200) .body("status", Matchers.is("UP")); return true; - } catch (AssertionError e) { - log.info("Caching service is down", e); + } catch (Throwable t) { + log.info("Caching service is down", t); return false; } } From 039b5687d1a36b379ea1a296ba3706484618409f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Thu, 11 Dec 2025 17:54:37 +0100 Subject: [PATCH 42/45] fix test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../security/service/token/ApimlAccessTokenProviderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java b/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java index 3eccfcd6dc..a303463e8c 100644 --- a/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java +++ b/gateway-service/src/test/java/org/zowe/apiml/gateway/security/service/token/ApimlAccessTokenProviderTest.java @@ -235,10 +235,10 @@ void givenUnexpectedError_whenReadSalt_thenThrowIt() { @Test void givenNoSaltInCache_whenInitializing_thenCreateNewOne() { - byte[] salt = "salt".getBytes(); Exception noRecordException = new CachingServiceClientException("no record"); doThrow(noRecordException).when(cachingServiceClient).read("salt"); - assertEquals(new String(salt), accessTokenProvider.initializeSalt()); + String salt = accessTokenProvider.initializeSalt(); + assertEquals(16, salt.length()); verify(cachingServiceClient, times(1)).create(any()); } From 8a93aeda7bcc25fbb79533be7015f0566c9beb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 12 Dec 2025 09:23:12 +0100 Subject: [PATCH 43/45] Revert "fix usage of truststore by caching service (key exchange)" This reverts commit c7466525c1b1dabd19d5d57bd9493689efce7829. --- .../infinispan/config/InfinispanConfig.java | 25 ------------------ .../src/main/resources/infinispan.xml | 3 --- keystore/docker/all-services.keystore.p12 | Bin 4638 -> 5854 bytes 3 files changed, 28 deletions(-) diff --git a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java index 128a7ff067..3983038b19 100644 --- a/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java +++ b/caching-service/src/main/java/org/zowe/apiml/caching/service/infinispan/config/InfinispanConfig.java @@ -58,9 +58,6 @@ public class InfinispanConfig implements InitializingBean { private static final String SERVER_SSL_KEY_STORE_TYPE = "server.ssl.keyStoreType"; private static final String SERVER_SSL_KEY_STORE = "server.ssl.keyStore"; private static final String SERVER_SSL_KEY_STORE_PASSWORD = "server.ssl.keyStorePassword"; - private static final String SERVER_SSL_TRUST_STORE_TYPE = "server.ssl.trustStoreType"; - private static final String SERVER_SSL_TRUST_STORE = "server.ssl.trustStore"; - private static final String SERVER_SSL_TRUST_STORE_PASSWORD = "server.ssl.trustStorePassword"; @Value("${caching.storage.infinispan.initialHosts}") private String initialHosts; @@ -74,15 +71,6 @@ public class InfinispanConfig implements InitializingBean { @Value("${server.ssl.keyStorePassword}") private String keyStorePass; - @Value("${server.ssl.trustStoreType}") - private String trustStoreType; - - @Value("${server.ssl.trustStore}") - private String trustStore; - - @Value("${server.ssl.trustStorePassword}") - private String trustStorePass; - @Value("${jgroups.bind.port}") private String port; @@ -111,10 +99,6 @@ void updateKeyring() { keyStore = formatKeyringUrl(keyStore); if (StringUtils.isBlank(keyStorePass)) keyStorePass = KEYRING_PASSWORD; } - if (isKeyring(trustStore)) { - trustStore = formatKeyringUrl(trustStore); - if (StringUtils.isBlank(trustStorePass)) trustStorePass = KEYRING_PASSWORD; - } } static String getRootFolder() { @@ -143,17 +127,11 @@ synchronized DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { Optional oldKeyStoreType = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE_TYPE")); Optional oldKeyStore = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE")); Optional oldKeyStorePassword = Optional.ofNullable(System.getProperty("SERVER_SSL_KEY_STORE_PASSWORD")); - Optional oldTrustStoreType = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE_TYPE")); - Optional oldTrustStore = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE")); - Optional oldTrustStorePassword = Optional.ofNullable(System.getProperty("SERVER_SSL_TRUST_STORE_PASSWORD")); if (!isServerAttlsEnabled) { System.setProperty(SERVER_SSL_KEY_STORE_TYPE, keyStoreType); System.setProperty(SERVER_SSL_KEY_STORE, keyStore); System.setProperty(SERVER_SSL_KEY_STORE_PASSWORD, keyStorePass); - System.setProperty(SERVER_SSL_TRUST_STORE_TYPE, trustStoreType); - System.setProperty(SERVER_SSL_TRUST_STORE, trustStore); - System.setProperty(SERVER_SSL_TRUST_STORE_PASSWORD, trustStorePass); } ConfigurationBuilderHolder holder; @@ -185,9 +163,6 @@ synchronized DefaultCacheManager cacheManager(ResourceLoader resourceLoader) { oldKeyStoreType.ifPresent(keystoreType -> System.setProperty(SERVER_SSL_KEY_STORE_TYPE, keystoreType)); oldKeyStore.ifPresent(keystore -> System.setProperty(SERVER_SSL_KEY_STORE, keystore)); oldKeyStorePassword.ifPresent(keystorePassword -> System.setProperty(SERVER_SSL_KEY_STORE_PASSWORD, keystorePassword)); - oldTrustStoreType.ifPresent(trueststoreType -> System.setProperty(SERVER_SSL_TRUST_STORE_TYPE, trueststoreType)); - oldTrustStore.ifPresent(truststore -> System.setProperty(SERVER_SSL_TRUST_STORE, truststore)); - oldTrustStorePassword.ifPresent(truststorePassword -> System.setProperty(SERVER_SSL_TRUST_STORE_PASSWORD, truststorePassword)); return cacheManager; } diff --git a/caching-service/src/main/resources/infinispan.xml b/caching-service/src/main/resources/infinispan.xml index b4cab80c31..d80c07d6b6 100644 --- a/caching-service/src/main/resources/infinispan.xml +++ b/caching-service/src/main/resources/infinispan.xml @@ -26,9 +26,6 @@ diff --git a/keystore/docker/all-services.keystore.p12 b/keystore/docker/all-services.keystore.p12 index 114f9648acba65d1fc87831595b56149c5a04080..6424a833f6e439a35d8ad4279163aaed9e74f8c1 100644 GIT binary patch delta 4365 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 H0s;sCtFczL delta 3139 zcmV-J47~H+EuJJIFoF^q0s#Xsf)UgP2`Yw2hW8Bt2LYgh5yb?85y3Em5xub@x&<5z z0R{;whDe6@4FLxRpn?nXFoFy20s#Opf(z%9_ysE%A>#AoIS=sAwlcu(be^6q4c%qwR2t|n9{6Qk>CNyK`i?~KS zz3+InfdLt3^9EK+M)W3gwSSWv>|Ikm&u}4DpRlsQz3NY9h!xM^xxoYewM*p&{BdX* zhZeEKpP{pquqHuOYlF(mM@S0k=6YcVA2|jyFU>`NeGRAFL~{${JDZgdPD8FCFnZ;M zq;4{MM145EHW@*G9ilA9xeHpK1=hv(@a4(b9p^l(TGFqX-OO9q+?bbp>OKcLnQBKo5H%cWuAF73>=V}|6_-`+{OcYnT*(n9exM^di8KDe(dsKwAcl)ZAu zjbaWvtUhrMrfA0$ZU)xoxPKwCS8dfo)JZ8-E}Az&xqMdStrq^dJ+(-G5xbjAV6~I^ zuLG+JxOYB8A@NdAF$N`P>)_9f=<&U#X#-Gyv#mUoZgjga=-^p8mGdqEbkbqk-SM3M zJG|<#29Rxy8h)bwz#`HHPmHSY4+ZuJa0m<8__UZAG2FPg?%5^VC#51eT3`bzH^J|J zm2tZlM0KT(e)s}$tU{sm=t0cJCJ#T-s=nkEVt6bk@*|=oJ7K>c-y;1=;bBx=e56(XrfY@fOy_QOD zPX|yZ4AEc%ZP-Xl{DLh^+_j?6Eb_H~U4{#rb%rmZvPXVXX#6;|D^6K6?)Nhnva&7y z4C0U1S5S2ez5cgwC(ETkAU4715v6A6#{n2~Q0zM|^z(b0wc*Cec?WncHHPE4C+r~F z!lfZ{PEdEE^=iaGLBNI)Yd5Zho(?hEsN3h*Vsm<80rXjM6%h~r`!h-xO7$y$Kst2l zbh*yeL}aUbdYam)1BBwlB!H;%iihqFHFl7q=6O&K>5oTglJsj1Rn_0E%M_*};RZ8p zJogyR<4E#)pg>{q!+isCrj)AN0!aTJH(Y5ia1v^_UFV~M$uN(&?frD^qY)`vqNcvp z3P1Z+TU1s|5gO^h$I_4AJ;yD7Lw8?w?g^QSkvZYiZ&*&7nksr`&IV-YDccGih#i*8 zf_(9H49=_Y1acPh9806O;xxWH(8Zv)(RG>82Cqk*@sSS2P4{SVL zE{WDaiy9KH7UjG5Z0ns z4E?H8W`$nS!H*@VT}Lq(4?XnngcrlFh1@O=IC}mfzP#f4Xw0C>cy7_?Zv#UxP2-4BbbX#Q3Py;Gi}~mG^7h zvvq@kfHOV6kJ}#&38~b7V#u-1h`dNDPtW-_!Xd0pCo*f*!my$kka)Uu%z$oWz$RM1 zPws%EEv~ZqGcTdmMjRYARa5@Wuo&e*$2@bnkj}v0F@^uWL6?Q4Q|_ z1Jt>Ck$I5)Czj9~9Yle*u)mIQC%lDD#5LH+KP`rB+Bg;G!+8wAg z%7TaT9sG3I;1n^n5R@v!c}sj)dJlZg0t?zoB0D0WuF=hZU2=K>J?B+6IzR5qYIoIY zb6&TO;7!(=-4Aek2t2(qL&FcO24eECdwitdi#dsDx{m_>FPd7@!3#iP7Or($P-Tjp{b0CM6;x|2%lXcpyHwYmVOL15`J$&2B@pvj#Fxx+fsvzqT$j zzR%}&x&+7MTb?eJ#edxuRR{+RjhJjIW6B=r5D7Dr23l*uGtR`(a)(OceH#Bv(Oq4j z941sW+i-#6sB{S!_Cu22CT_x0I%K6j{Vg4TR7qv)Z=}_2`LdX?jbA;6?m5$t?4-j< z4{82arbhOb3k!85!xz%z@FfDg#-6Dxobx|)SNeJyY;hF@7f!wST>L*rqTxzec`=5oq@AUO?{>*S6`-=6!9c7;v-$Ea z`Wz2#oEVO7H6T62jx+xqQU!?BSZ7b%e((G7;5aSOH`nZ|koBXwU z-zSm|omwDuAf$;D%e=z+>!9|&1^fnmt@G^3u>v@8JvCYy2d&X9b*^|<0NPW3^$~dS z=wmZxo5yM7gpRl=Lp9UftMKd4maD)qgp4fJGdy(vHqZj`2fmUIgFn8y;k=WD22H9G zCVqA*3gaD69#?7=<~y24IdrcSkNXC&mJQU=NB<(Jrl`%wRzFxcXI?5SGAGtFE&lu7 z?j*5t;ss&cisS~ANcmJtw@raORwyD14 zD^0O9IkbMW-8Gg<&f$^0%U@;3>shP?3RnmSW{#<6}zMC!lcn`Z0R1dECJWMccEL>YE z2mp$WIa9!-cEgbzbSNQz?P|E=@PgaN9n@+^f~yAKsgwrpA|3>G2Qo^j)j%Q(XKq&` zpvZk(NVb_f|4~sW{KXpF*!BNr`11k+2mrSj7GeMZ From 4aeb7c1ed0cd4a4461ff25141b204850e41bff61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 12 Dec 2025 10:58:40 +0100 Subject: [PATCH 44/45] IT extension for tokenCache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- .../apiml/integration/ha/CachingService.java | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java index 60c9175154..bbb068fb89 100644 --- a/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java +++ b/integration-tests/src/test/java/org/zowe/apiml/integration/ha/CachingService.java @@ -50,8 +50,13 @@ public class CachingService { private static final String SERVICE = "service"; private static final String KEY = "aCacheKey" + new Random().nextInt(); private static final String VALUE = "aCacheValue"; + private static final String MAP = "aMap"; + private static final String MAP_KEY = "aMapCacheKey" + new Random().nextInt(); + private static final String MAP_VALUE = "aMapCacheValue"; + private static final String DN = "CN=Zowe Service, OU=API Mediation Layer, O=Zowe Sample, L=Prague, ST=Prague, C=CZ"; private static final KeyValue KEY_VALUE = new KeyValue(KEY, VALUE); + private static final KeyValue MAP_KEY_VALUE = new KeyValue(MAP_KEY, MAP_VALUE); private Credentials credentials; private List baseUrls; @@ -109,12 +114,44 @@ void setUp() throws Exception { .until(this::isUp); } + private void assertContent(int index) { + // check the all records (tokenCache) + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", DN) + .when() + .get(baseUrls.get(index) + "/cachingservice/api/v1/cache-list") + .then() + .statusCode(200) + .body(MAP + "." + MAP_KEY, equalTo(MAP_VALUE)); + + // check the all records (tokenCache) + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", DN) + .when() + .get(baseUrls.get(index) + "/cachingservice/api/v1/cache-list/" + MAP) + .then() + .statusCode(200) + .body(MAP_KEY, equalTo(MAP_VALUE)); + + // check the concrete record (cache) + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", DN) + .when() + .get(baseUrls.get(index) + "/cachingservice/api/v1/cache/" + KEY) + .then() + .statusCode(200) + .body("value", equalTo(VALUE)); + } + @Test void givenMultipleInstances_whenShareAValue_thenShutdownDoesntChangeTheState() { - log.info("Set value on the first instance"); + log.info("Set value on the first instance to cache storage"); given() .config(SslContext.clientCertApiml) - .header("X-Certificate-DistinguishedName", SERVICE) + .header("X-Certificate-DistinguishedName", DN) .contentType(JSON) .body(KEY_VALUE) .when() @@ -122,6 +159,17 @@ void givenMultipleInstances_whenShareAValue_thenShutdownDoesntChangeTheState() { .then() .statusCode(201); + log.info("Set value on the first instance to tokenCache storage"); + given() + .config(SslContext.clientCertApiml) + .header("X-Certificate-DistinguishedName", DN) + .contentType(JSON) + .body(MAP_KEY_VALUE) + .when() + .post(baseUrls.get(0) + "/cachingservice/api/v1/cache-list/" + MAP) + .then() + .statusCode(201); + int instances = baseUrls.size(); for (int i = -1; i < instances - 1; i++) { if (i >= 0) { @@ -138,14 +186,7 @@ void givenMultipleInstances_whenShareAValue_thenShutdownDoesntChangeTheState() { for (int j = i + 1; j < instances; j++) { log.info("Check if the value is accessible {}. instance", j + 1); - given() - .config(SslContext.clientCertApiml) - .header("X-Certificate-DistinguishedName", SERVICE) - .when() - .get(baseUrls.get(j) + "/cachingservice/api/v1/cache/" + KEY) - .then() - .statusCode(200) - .body("value", equalTo(VALUE)); + assertContent(j); } } From cb7cd75c6d831974a40ae588513ab57bcfe1679d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jare=C5=A1?= Date: Fri, 12 Dec 2025 14:11:48 +0100 Subject: [PATCH 45/45] improve log message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pavel Jareš --- caching-service/src/main/resources/caching-log-messages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caching-service/src/main/resources/caching-log-messages.yml b/caching-service/src/main/resources/caching-log-messages.yml index 82bf156b02..de8daf9fb3 100644 --- a/caching-service/src/main/resources/caching-log-messages.yml +++ b/caching-service/src/main/resources/caching-log-messages.yml @@ -120,5 +120,5 @@ messages: type: WARNING text: "Cache is not available: %s" reason: "Cache is not ready to write at the moment." - action: "Verify the instance configuration or connectivity between multiple instances." + action: "Wait till initialization of cache is done. In case it is done verify the instance configuration or connectivity between multiple instances."