diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8448c970e..5821cfd85 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,9 +12,9 @@ on: env: GH_USER_NAME: github.actor SCRIPTS_VERSION: 5.10.0 - BOM_VERSION: 5.10.0 - MIGRATIONS_VERSION: 5.10.0 - RELEASE_VERSION: 5.10.0 + BOM_VERSION: 5.11.0 + MIGRATIONS_VERSION: 5.11.0 + RELEASE_VERSION: 5.11.0 jobs: release: diff --git a/build.gradle b/build.gradle index 7066710e7..b0611eb4d 100644 --- a/build.gradle +++ b/build.gradle @@ -95,10 +95,12 @@ dependencies { annotationProcessor "org.projectlombok:lombok:${lombokVersion}" testCompileOnly "org.projectlombok:lombok:${lombokVersion}" testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" + implementation 'org.springframework.boot:spring-boot-starter-cache' + implementation 'com.github.ben-manes.caffeine:caffeine' testCompile 'org.springframework.boot:spring-boot-starter-test' testCompile 'org.flywaydb.flyway-test-extensions:flyway-spring-test:6.1.0' - + } dependencyCheck { diff --git a/gradle.properties b/gradle.properties index 4b30a6367..164f739ab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -version=5.10.0 -lombokVersion=1.18.30 +version=5.11.1 +lombokVersion=1.18.30 \ No newline at end of file diff --git a/src/main/java/com/epam/ta/reportportal/config/ApiKeyCacheResolver.java b/src/main/java/com/epam/ta/reportportal/config/ApiKeyCacheResolver.java index 69c07b369..790707033 100644 --- a/src/main/java/com/epam/ta/reportportal/config/ApiKeyCacheResolver.java +++ b/src/main/java/com/epam/ta/reportportal/config/ApiKeyCacheResolver.java @@ -1,9 +1,25 @@ +/* + * Copyright 2023 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.epam.ta.reportportal.config; import com.epam.ta.reportportal.dao.ApiKeyRepository; import com.epam.ta.reportportal.entity.user.ApiKey; import java.util.ArrayList; import java.util.Collection; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.interceptor.CacheOperationInvocationContext; @@ -23,7 +39,8 @@ public class ApiKeyCacheResolver implements CacheResolver { private final CacheManager cacheManager; - public ApiKeyCacheResolver(ApiKeyRepository apiKeyRepository, CacheManager cacheManager) { + public ApiKeyCacheResolver(ApiKeyRepository apiKeyRepository, + @Qualifier("caffeineCacheManager") CacheManager cacheManager) { this.apiKeyRepository = apiKeyRepository; this.cacheManager = cacheManager; } @@ -31,17 +48,23 @@ public ApiKeyCacheResolver(ApiKeyRepository apiKeyRepository, CacheManager cache @Override @NonNull public Collection resolveCaches(CacheOperationInvocationContext context) { - Long apiKeyId = (Long) context.getArgs()[0]; - ApiKey apiKey = apiKeyRepository.findById(apiKeyId).orElse(null); - + Cache cache = cacheManager.getCache("apiKeyCache"); Collection caches = new ArrayList<>(); - if (apiKey != null && context.getOperation().getCacheNames().contains("apiKeyCache")) { - Cache cache = cacheManager.getCache("apiKeyCache"); - if (cache != null) { - cache.evict(apiKey.getHash()); - caches.add(cache); + + if (cache != null) { + caches.add(cache); + + Object arg = context.getArgs()[0]; + + if (context.getMethod().getName().equals("deleteById") && arg instanceof Long) { + Long apiKeyId = (Long) arg; + ApiKey apiKey = apiKeyRepository.findById(apiKeyId).orElse(null); + if (apiKey != null) { + cache.evict(apiKey.getHash()); + } } } + return caches; } } \ No newline at end of file diff --git a/src/main/java/com/epam/ta/reportportal/config/CacheConfiguration.java b/src/main/java/com/epam/ta/reportportal/config/CacheConfiguration.java new file mode 100644 index 000000000..d37b3547a --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/config/CacheConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright 2023 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.epam.ta.reportportal.config; + +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.concurrent.TimeUnit; +import org.springframework.cache.CacheManager; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for cache manager. + * + * @author Ivan Kustau + */ +@Configuration +public class CacheConfiguration { + + @Bean("caffeineCacheManager") + public CacheManager cacheManager() { + CaffeineCacheManager cacheManager = new CaffeineCacheManager(); + cacheManager.setCaffeine(cacheProperties()); + return cacheManager; + } + + private Caffeine cacheProperties() { + return Caffeine.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS); + } +} diff --git a/src/main/java/com/epam/ta/reportportal/dao/ApiKeyRepository.java b/src/main/java/com/epam/ta/reportportal/dao/ApiKeyRepository.java index 5aea2d17c..d41412068 100644 --- a/src/main/java/com/epam/ta/reportportal/dao/ApiKeyRepository.java +++ b/src/main/java/com/epam/ta/reportportal/dao/ApiKeyRepository.java @@ -36,7 +36,7 @@ public interface ApiKeyRepository * @param hash hash of api key * @return {@link ApiKey} */ - @Cacheable(value = "apiKeyCache", key = "#hash") + @Cacheable(value = "apiKeyCache", key = "#hash", cacheResolver = "apiKeyCacheResolver") ApiKey findByHash(String hash); /** diff --git a/src/test/java/com/epam/ta/reportportal/config/TestConfiguration.java b/src/test/java/com/epam/ta/reportportal/config/TestConfiguration.java index a3cc2652e..92b25bb02 100644 --- a/src/test/java/com/epam/ta/reportportal/config/TestConfiguration.java +++ b/src/test/java/com/epam/ta/reportportal/config/TestConfiguration.java @@ -22,11 +22,15 @@ import com.epam.reportportal.commons.TikaContentTypeResolver; import com.epam.ta.reportportal.filesystem.DataEncoder; import com.epam.ta.reportportal.util.FeatureFlagHandler; +import com.github.benmanes.caffeine.cache.Caffeine; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cache.CacheManager; +import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -69,4 +73,15 @@ public DataEncoder dataEncoder() { return new DataEncoder(); } + @Bean(name = "caffeineCacheManager") + public CacheManager cacheManager() { + CaffeineCacheManager cacheManager = new CaffeineCacheManager(); + cacheManager.setCaffeine(cacheProperties()); + return cacheManager; + } + + private Caffeine cacheProperties() { + return Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES); + } + }