Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
Resolved issue #232
Browse files Browse the repository at this point in the history
  • Loading branch information
Renat Yalalov authored and DariaMitrofanovna committed May 5, 2022
1 parent f09e144 commit 61a9437
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*-
* #%L
* IO Tesler - Core
* %%
* Copyright (C) 2018 - 2019 Tesler Contributors
* %%
* 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.
* #L%
*/

package io.tesler.core.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface AutoConfiguration {

@AliasFor(annotation = Configuration.class, attribute = "proxyBeanMethods")
boolean proxyBeanMethods() default true;

@AliasFor(annotation = Configuration.class, attribute = "value")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@
* #L%
*/

package io.tesler.core.config.cache;

package io.tesler.core.autoconfigure.cache;

import com.google.common.collect.ImmutableList;
import io.tesler.core.autoconfigure.AutoConfiguration;
import io.tesler.core.config.cache.CacheConfig;
import io.tesler.core.config.cache.CacheManagerBasedCacheResolver;
import io.tesler.core.config.cache.TeslerCaches;
import io.tesler.core.config.cache.TeslerRequestAwareCacheHolder;
import io.tesler.core.metahotreload.MetaHotReloadService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
Expand All @@ -42,16 +51,22 @@
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

@Configuration
/**
* <p>Auto-configuration class which declares "teslerCacheResolver" bean of type CacheResolver.</p>
* <p>As it says in the Spring documentation:</p>
* <p><strong>Auto-configuration is non-invasive. At any point, you can start to define your own configuration to replace specific parts of the auto-configuration.</strong></p>
* <p>It follows that if you declare a bean with name "teslerCacheResolver" and type {@link CacheResolver CacheResolver} in a project, which defines dependency on Tesler, this autoconfiguration will be ignored, otherwise it will create the "teslerCacheResolver" bean {@link #teslerCacheResolver defined below}.
* A bean named "teslerCacheResolver" is used by Tesler in all annotations which are related to Spring cache abstraction.</p>
* <p>{@link AutoConfiguration @AutoConfiguration} is nothing but alias for {@link org.springframework.context.annotation.Configuration @Configuration},
* it is used to exclude a class from component scanning (see {@link io.tesler.core.config.BeanScan @BeanScan}).</p>
*
* @see CacheManagerBasedCacheResolver
*/
@AutoConfiguration
@ConditionalOnClass({CacheManager.class})
@ConditionalOnMissingBean(name = "teslerCacheResolver")
@ConditionalOnBean({CacheAspectSupport.class})
Expand All @@ -67,17 +82,12 @@ public class TeslerCacheAutoConfiguration {
public CacheResolver teslerCacheResolver(MetaHotReloadService metaHotReloadService) {
metaHotReloadService.loadMeta();
if (CacheType.NONE.equals(cacheProperties.getType())) {
return new TeslerCacheResolver(new NoOpCacheManager());
return new CacheManagerBasedCacheResolver(new NoOpCacheManager());
}
CompositeCacheManager compositeCacheManager = new CompositeCacheManager();
compositeCacheManager.setCacheManagers(buildCacheManagers());
compositeCacheManager.setFallbackToNoOpCache(true);
return new TeslerCacheResolver(compositeCacheManager);
}

@Bean
public TeslerRequestAwareCacheHolder userCache() {
return new TeslerRequestAwareCacheHolder(new ConcurrentMapCache(CacheConfig.USER_CACHE));
return new CacheManagerBasedCacheResolver(compositeCacheManager);
}

@Bean
Expand All @@ -86,25 +96,23 @@ public TeslerRequestAwareCacheHolder requestCache() {
return new TeslerRequestAwareCacheHolder(new ConcurrentMapCache(CacheConfig.REQUEST_CACHE));
}


protected List<CacheManager> buildCacheManagers() {
List<CacheManager> result = new ArrayList<>();
result.add(buildUnExpirableCacheManager(
TeslerCaches.getSimpleCacheNames().toArray(new String[0])
));
result.add(buildRequestAwareCacheManager(TeslerCaches.getRequestCaches()));
result.add(buildRequestAwareCacheManager(TeslerCaches.getRequestCacheName()));
return result;
}

protected CacheManager buildUnExpirableCacheManager(String... names) {
return new ConcurrentMapCacheManager(names);
}

protected CacheManager buildRequestAwareCacheManager(List<String> cacheNames) {
protected CacheManager buildRequestAwareCacheManager(String cacheName) {
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
simpleCacheManager.setCaches(cacheNames.stream()
.map(RequestAwareCacheDecorator::new)
.collect(Collectors.toList())
simpleCacheManager.setCaches(
ImmutableList.of(new RequestAwareCacheDecorator(cacheName))
);
simpleCacheManager.initializeCaches();
return simpleCacheManager;
Expand Down
2 changes: 2 additions & 0 deletions tesler-core/src/main/java/io/tesler/core/config/BeanScan.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package io.tesler.core.config;

import io.tesler.api.util.spring.ServiceBasedComponentExcludeFilter;
import io.tesler.core.autoconfigure.AutoConfiguration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand All @@ -45,6 +46,7 @@
@Filter(value = {Aspect.class}, type = FilterType.ANNOTATION)
},
excludeFilters = {
@Filter(value = {AutoConfiguration.class}, type = FilterType.ANNOTATION),
@Filter(value = {Controller.class, ControllerAdvice.class}, type = FilterType.ANNOTATION),
@Filter(value = {
WebMvcConfigurer.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@
import io.tesler.model.core.dao.JpaDao;
import io.tesler.model.core.service.BaseEntityListenerDelegate;
import io.tesler.model.core.service.TeslerBaseEntityListenerDelegate;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;


@EnableAspectJAutoProxy
@BeanScan({"io.tesler"})
@EnableSpringConfigured
@ImportAutoConfiguration({
@Import({
MetaHotReloadConfiguration.class,
TeslerFileConfiguration.class
})
Expand All @@ -58,4 +58,5 @@ public ResponsibilitiesService responsibilitiesService(JpaDao jpaDao) {
public BaseEntityListenerDelegate baseEntityListenerDelegate(CurrentUserAware currentUserAware) {
return new TeslerBaseEntityListenerDelegate(currentUserAware);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
import org.springframework.cache.interceptor.CacheResolver;

@Slf4j
@RequiredArgsConstructor
public class TeslerCacheResolver implements CacheResolver {
public class CacheManagerBasedCacheResolver implements CacheResolver {

private final CacheManager teslerCachesManager;

@NotNull
@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
Set<String> cacheNames = context.getOperation().getCacheNames();
if (cacheNames == null) {
if (cacheNames.isEmpty()) {
return Collections.emptyList();
}
List<Cache> result = new ArrayList<>(cacheNames.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@

package io.tesler.core.config.cache;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.UtilityClass;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.experimental.UtilityClass;

@UtilityClass
public class TeslerCaches {
Expand All @@ -38,24 +36,30 @@ public static List<String> getSimpleCacheNames() {
.collect(Collectors.toList());
}

public static List<String> getRequestCaches() {
return Arrays.stream(Caches.values())
.filter(Caches::isRequestScope)
.map(Caches::name)
.collect(Collectors.toList());
public static String getRequestCacheName() {
return Caches.requestCache.name();
}

@AllArgsConstructor

@Getter
public enum Caches {
linkedDictionaryRules(false),
specifications(false),
widgetcache(false),
notificationSettings(false),
workflow(false),
linkedDictionaryRules,
specifications,
widgetcache,
notificationSettings,
workflow,
requestCache(true),
userCache(true);
userCache;

private final boolean requestScope;

Caches(boolean requestScope) {
this.requestScope = requestScope;
}

Caches() {
this.requestScope = false;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import javax.annotation.Nullable;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
Expand Down
2 changes: 1 addition & 1 deletion tesler-core/src/main/resources/META-INF/spring.factories
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.tesler.core.config.cache.TeslerCacheAutoConfiguration
io.tesler.core.autoconfigure.cache.TeslerCacheAutoConfiguration

0 comments on commit 61a9437

Please sign in to comment.