Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cast lep context to map #244

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/version.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import java.util.regex.Pattern

version = "3.2.0"//detectSemVersion()
version = "3.2.1"//detectSemVersion()
logger.lifecycle("Project version: $version")

String detectSemVersion() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.icthh.xm.commons.lep.spring;

import com.icthh.xm.commons.lep.XmLepScriptConfigServerResourceLoader;
import com.icthh.xm.commons.lep.api.LepManagementService;
import com.icthh.xm.commons.security.spring.config.XmAuthenticationContextConfiguration;
import com.icthh.xm.commons.tenant.TenantContextHolder;
import com.icthh.xm.commons.tenant.TenantContextUtils;
import com.icthh.xm.commons.tenant.spring.config.TenantContextConfiguration;
import lombok.SneakyThrows;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Map;

import static com.icthh.xm.commons.lep.spring.DynamicLepClassResolveIntTest.loadFile;
import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
DynamicLepTestConfig.class,
TenantContextConfiguration.class,
XmAuthenticationContextConfiguration.class
})
@ActiveProfiles("resolveclasstest")
public class LepIntTest {

@Autowired
private LepManagementService lepManagerService;

@Autowired
private TenantContextHolder tenantContextHolder;

@Autowired
private DynamicTestLepService testLepService;

@Autowired
private XmLepScriptConfigServerResourceLoader resourceLoader;

@Before
public void init() {
TenantContextUtils.setTenant(tenantContextHolder, "TEST");
lepManagerService.beginThreadContext();
}

@Test
@SneakyThrows
public void testLepContextCastToMap() {
String code = loadFile("lep/TestLepContextCastToMap.groovy");
resourceLoader.onRefresh("/config/tenants/TEST/testApp/lep/service/TestLepMethodWithInput$$around.groovy", code);
String result = testLepService.testLepMethod(Map.of("parameter", "testValue"));
assertEquals("testValue", result);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import groovy.util.logging.Slf4j

@Slf4j
class Service {
Map<String, Object> lepContext

public Service(Map<String, Object> lepContext) {
log.info("lepContext.inArgs.input.parameter {}", lepContext.inArgs.input.parameter)
this.lepContext = lepContext
}
}
return new Service(lepContext).lepContext.inArgs.input.parameter
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
import com.icthh.xm.commons.lep.spring.lepservice.LepServiceFactory;
import com.icthh.xm.commons.security.XmAuthenticationContext;
import com.icthh.xm.commons.tenant.TenantContext;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.experimental.Delegate;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public abstract class BaseLepContext {
import static java.util.Optional.ofNullable;

public abstract class BaseLepContext implements Map<String, Object> {

public Object commons;
public Object inArgs;
Expand All @@ -22,14 +28,30 @@ public abstract class BaseLepContext {
public Object methodResult;
public LepServiceFactory lepServices;

private Map<String, Object> additionalContext = new HashMap<>();
private transient Map<String, Object> additionalContext = new HashMap<>();
@Setter
private transient LepContextMapSupport mapSupport;
@Delegate(excludes = ExcludedMethods.class)
private transient Map<String, Object> emptyMap = Map.of();

public final Object get(Object fieldName) {
if (mapSupport == null) { // fallback to reflection. to simplify groovy tests
return ofNullable(additionalContext.get(fieldName)).orElseGet(() -> getFieldValue(fieldName));
}
return ofNullable(mapSupport.get(String.valueOf(fieldName), this)).orElse(additionalContext.get(fieldName));
}

public final Object get(String additionalContextKey) {
return additionalContext.get(additionalContextKey);
@SneakyThrows
private Object getFieldValue(Object fieldName) {
return this.getClass().getField(String.valueOf(fieldName)).get(this);
}

public final void addAdditionalContext(String additionalContextKey, Object additionalContextValue) {
additionalContext.put(additionalContextKey, additionalContextValue);
}

private interface ExcludedMethods {
Object get(Object key);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.icthh.xm.commons.lep.api;

import com.icthh.xm.commons.logging.util.BasePackageDetector;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import org.springframework.stereotype.Component;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.function.Predicate.not;

public class LepContextMapSupport {
private final Map<Class<? extends BaseLepContext>, Map<String, VarHandle>> classFieldHandles = new HashMap<>();

public LepContextMapSupport(BasePackageDetector basePackageDetector) {
this(basePackageDetector.getBasePackage());
}

public LepContextMapSupport(String basePackage) {
Reflections reflections = new Reflections(basePackage);
Set<Class<? extends BaseLepContext>> classes = reflections.getSubTypesOf(BaseLepContext.class);
initializeVarHandles(classes);
}

@SneakyThrows
private void initializeVarHandles(Set<Class<? extends BaseLepContext>> classes) {
MethodHandles.Lookup lookup = MethodHandles.lookup();
for (Class<? extends BaseLepContext> type : classes) {
Map<String, VarHandle> fieldHandles = new HashMap<>();
for (Field field : getFields(type)) {
VarHandle handle = lookup.unreflectVarHandle(field);
fieldHandles.put(field.getName(), handle);
}
classFieldHandles.put(type, fieldHandles);
}
}

private List<Field> getFields(Class<? extends BaseLepContext> type) {
return Stream.of(type.getFields())
.filter(not(Field::isSynthetic))
.filter(it -> !Modifier.isStatic(it.getModifiers()))
.collect(Collectors.toList());
}

public Object get(String fieldName, BaseLepContext instance) {
VarHandle handle = classFieldHandles.get(instance.getClass()).get(fieldName);
return handle == null ? null : handle.get(instance);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
package com.icthh.xm.commons.lep.impl.utils;

import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.icthh.xm.commons.lep.api.XmLepConfigFile;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.Scanner;
import org.reflections.scanners.Scanners;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.icthh.xm.commons.lep.api.BaseLepContext;
import com.icthh.xm.commons.lep.api.LepAdditionalContext;
import com.icthh.xm.commons.lep.api.LepContextFactory;
import com.icthh.xm.commons.lep.api.LepContextMapSupport;
import com.icthh.xm.commons.lep.api.LepEngine;
import com.icthh.xm.commons.lep.commons.CommonsExecutor;
import com.icthh.xm.commons.lep.commons.CommonsService;
Expand All @@ -28,6 +29,7 @@ public class LepContextService {
private final XmAuthenticationContextHolder xmAuthContextHolder;
private final List<LepAdditionalContext<?>> additionalContexts;
private final CommonsService commonsService;
private final LepContextMapSupport lepContextMapSupport;

public final BaseLepContext createLepContext(LepEngine lepEngine, TargetProceedingLep lepMethod) {
BaseLepContext baseLepContext = lepContextFactory.buildLepContext(lepMethod);
Expand All @@ -37,6 +39,7 @@ public final BaseLepContext createLepContext(LepEngine lepEngine, TargetProceedi
baseLepContext.tenantContext = tenantContextHolder.getContext();
baseLepContext.authContext = xmAuthContextHolder.getContext();
baseLepContext.commons = new CommonsExecutor(commonsService);
baseLepContext.setMapSupport(lepContextMapSupport);
additionalContexts.forEach(context ->
baseLepContext.addAdditionalContext(context.additionalContextKey(), context.additionalContextValue()));
baseLepContext.lepServices = new LepServiceFactoryImpl(lepEngine.getId(), lepServiceFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.icthh.xm.commons.lep.api.BaseLepContext;
import com.icthh.xm.commons.lep.api.LepAdditionalContext;
import com.icthh.xm.commons.lep.api.LepContextFactory;
import com.icthh.xm.commons.lep.api.LepContextMapSupport;
import com.icthh.xm.commons.lep.api.LepEngine;
import com.icthh.xm.commons.lep.api.LepEngineFactory;
import com.icthh.xm.commons.lep.api.LepManagementService;
Expand All @@ -23,6 +24,7 @@
import com.icthh.xm.commons.lep.spring.lepservice.LepServiceFactoryWithLepFactoryMethod;
import com.icthh.xm.commons.lep.spring.web.LepInterceptor;
import com.icthh.xm.commons.logging.config.LoggingConfigService;
import com.icthh.xm.commons.logging.util.BasePackageDetector;
import com.icthh.xm.commons.security.XmAuthenticationContextHolder;
import com.icthh.xm.commons.tenant.TenantContextHolder;
import com.icthh.xm.lep.api.LepKeyResolver;
Expand Down Expand Up @@ -130,22 +132,35 @@ public LepServiceFactoryResolver lepServiceFactoryResolver() {
return new LepServiceFactoryResolver();
}

@Bean
public LepContextMapSupport lepContextMapSupport(BasePackageDetector basePackageDetector) {
return new LepContextMapSupport(basePackageDetector);
}

@Bean
@ConditionalOnMissingBean
public BasePackageDetector basePackageDetector(ApplicationContext applicationContext) {
return new BasePackageDetector(applicationContext);
}

@Bean
public LepContextService lepContextService(LepContextFactory lepContextFactory,
LepServiceFactoryWithLepFactoryMethod lepServiceFactory,
LepThreadHelper lepThreadHelper,
TenantContextHolder tenantContextHolder,
XmAuthenticationContextHolder xmAuthContextHolder,
List<LepAdditionalContext<?>> additionalContexts,
CommonsService commonsService) {
CommonsService commonsService,
LepContextMapSupport lepContextMapSupport) {
return new LepContextService(
lepContextFactory,
lepServiceFactory,
lepThreadHelper,
tenantContextHolder,
xmAuthContextHolder,
additionalContexts,
commonsService
commonsService,
lepContextMapSupport
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.Supplier;

public class LepThreadHelper {

Expand Down