среда, 6 августа 2025 г.

Expression resolver

 For example we have an anotation like @MyLog on method with some fields wich you wanna fill with expression language.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyLog {

/**
* Format: SpEl expression.
     * Could be used root context fields {@link MyLogExpressionRootObject}<br>
     * like {@code #root.result} or {@code #root.args}, {@code #root.args[0]}<br>
     * or by method field name {@code #fieldName}
*/
String value() default "";
}

@Slf4j
@Aspect
@RequiredArgsConstructor
public class MyLogInterceptor {

private final MyLogProcessor myLogProcessor;

@Around(value = "@annotation(myLogAnnotation)", argNames = "joinPoint,myLogAnnotation")
public Object intercept(ProceedingJoinPoint joinPoint, MyLog myLogAnnotation) throws Throwable {
    var result = joinPoint.proceed();
    myLogProcessor.process(joinPoint, myLogAnnotation, result);
    return result;
    }
}

@Slf4j
public class MyLogProcessorImpl implements MyLogProcessor {

private final StandardEvaluationContext originalEvaluationContext;
private final MyLogExpressionEvaluator expressionEvaluator;
    public MyLogProcessorImpl(ConfigurableListableBeanFactory beanFactory) {
    this.originalEvaluationContext = new StandardEvaluationContext();
    this.originalEvaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
     this.expressionEvaluator = new MyLogExpressionEvaluator(originalEvaluationContext);
    }
    public void process(ProceedingJoinPoint joinPoint, MyLog myLogAnnotation, @Nullable Object result) {
        var targetMethod = getTargetMethod(joinPoint);
    var context = expressionEvaluator.createEvaluationContext(targetMethod, joinPoint.getArgs(), result);
    var annotatedElementKey = new AnnotatedElementKey(targetMethod, AopProxyUtils.ultimateTargetClass(joinPoint.getTarget()));
        var evaluatedValue = expressionEvaluator.getValue(myLogAnnotation.value(), annotatedElementKey, context);
    } 

    private String getValue(Object object) {
    return object != null ? object.toString() : null;
    }

    private Method getTargetMethod(final ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
    var signature = (MethodSignature) joinPoint.getSignature();
    if (!signature.getDeclaringType().isInterface()) {
    return signature.getMethod();
    }
    return joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
    }
}
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.context.expression.CachedExpressionEvaluator;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.lang.Nullable;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MyLogExpressionEvaluator extends CachedExpressionEvaluator {

private final Map<ExpressionKey, Expression> paramCache = new ConcurrentHashMap<>(64);

private final StandardEvaluationContext originalEvaluationContext;

MyLogExpressionEvaluator(StandardEvaluationContext originalEvaluationContext) {
this.originalEvaluationContext = originalEvaluationContext;
}

public Object getValue(String conditionExpression, AnnotatedElementKey methodKey, EvaluationContext context) {
return getExpression(this.paramCache, methodKey, conditionExpression).getValue(context);
}

/**
* Create an {@link EvaluationContext}.
*
* @param method the method
* @param args the method arguments
* @param result the return value (can be {@code null})
* @return the evaluation context
*/
public EvaluationContext createEvaluationContext(Method method, Object[] args, @Nullable Object result) {
var rootObject = new MyLogExpressionRootObject(args, result);
var evaluationContext = new MethodBasedEvaluationContext(rootObject, method, args, getParameterNameDiscoverer());
applyDelegatesTo(evaluationContext);
return evaluationContext;
}


/**
* copy past method to back compatibility with spring boot 2.
* in sb 3 method can be replaced with this.originalEvaluationContext.applyDelegatesTo(evaluationContext);
*/
private void applyDelegatesTo(StandardEvaluationContext evaluationContext) {
evaluationContext.setBeanResolver(this.originalEvaluationContext.getBeanResolver());
evaluationContext.setConstructorResolvers(new ArrayList<>(this.originalEvaluationContext.getConstructorResolvers()));
evaluationContext.setMethodResolvers(new ArrayList<>(this.originalEvaluationContext.getMethodResolvers()));
evaluationContext.setPropertyAccessors(new ArrayList<>(this.originalEvaluationContext.getPropertyAccessors()));
evaluationContext.setTypeLocator(this.originalEvaluationContext.getTypeLocator());
evaluationContext.setTypeConverter(this.originalEvaluationContext.getTypeConverter());
evaluationContext.setTypeComparator(this.originalEvaluationContext.getTypeComparator());
evaluationContext.setOperatorOverloader(this.originalEvaluationContext.getOperatorOverloader());
}
}
record MyLogExpressionRootObject(Object[] args, Object result) {
}

среда, 19 июля 2023 г.

Gloowroot

 https://glowroot.org/


Features

  • Trace capture for slow requests and errors
  • Continuous profiling (with very handy filtering)
  • Response time breakdown charts
  • Response time percentile charts
  • SQL capture and aggregation
  • Service call capture and aggregation
  • MBean attribute capture and charts
  • Configurable alerting
  • Historical rollup of all data (1m, 5m, 30m, 4h) with configurable retention
  • Full support for async requests that span multiple threads
  • Responsive UI with mobile support
  • Optional central collector

четверг, 2 февраля 2023 г.

Maven dependensy tree


Поиск того какие библиотеки тянут зависимость: 

mvn dependency:tree -Dincludes=org.slf4j 


ключ для отключения проверки сертов сервера:

-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true


Import the root certificate into the JVM trust store

  1. keytool -importcert -alias startssl -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -file ca.der

пятница, 24 июня 2022 г.

Maven test

 <plugin>

    <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} -Dfile.encoding=UTF-8 #supporting ru text in test</argLine>
    </configuration>
</plugin>

пятница, 27 мая 2022 г.

Json model generator

 


<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory>
<targetPackage>ru.company.model</targetPackage>
<includeAdditionalProperties>false</includeAdditionalProperties>
<generateBuilders>true</generateBuilders>
<serializable>true</serializable>
<formatDates>true</formatDates>
<formatDateTimes>true</formatDateTimes>
<inclusionLevel>NON_EMPTY</inclusionLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>

Валидация по json scheme

 

/**
* Получение строки из файла в ресурсах
*
* @param location- местоположение файла
* @return содержимое файла
*/
@SneakyThrows
public static String getJsonFromFile(String location) {
Resource resource = new DefaultResourceLoader().getResource(location);
return StreamUtils.copyToString(resource.getInputStream(), UTF_8);
}

/**
* Получение JSON схемы из файла
*
* @param source - местоположение файла с JSON схемой
* @return - схема
*/
@SneakyThrows
private static Schema getSchema(String source) {
JSONObject jsonObject = new JSONObject(new JSONTokener(new DefaultResourceLoader()
.getResource(source)
.getInputStream()));
return SchemaLoader.builder()
.schemaClient(SchemaClient.classPathAwareClient())
.schemaJson(jsonObject)
.resolutionScope(source)
.build().load().build();
}


private String SCHEMA_IN_RESOURCE = "classpath:/schema/MySchame.json";
Schema schema = getSchema(SCHEMA_IN_RESOURCE);
schema.validate(new org.json.JSONObject("{}"));