All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tosan.tools.tracker.starter.aspect.TrackerAspect Maven / Gradle / Ivy

The newest version!
package com.tosan.tools.tracker.starter.aspect;

import com.tosan.tools.tracker.starter.api.Tracking;
import com.tosan.tools.tracker.starter.model.RequestTrackEntity;
import com.tosan.tools.tracker.starter.model.ResponseTrackEntity;
import com.tosan.tools.tracker.starter.model.ServiceEntity;
import com.tosan.tools.tracker.starter.model.TrackType;
import com.tosan.tools.tracker.starter.service.StreamResponse;
import com.tosan.tools.tracker.starter.service.TrackerService;
import com.tosan.tools.tracker.starter.service.TrackingDataProvider;
import com.tosan.tools.tracker.starter.util.AnnotationUtil;
import jakarta.transaction.Transactional;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import java.util.Arrays;

/**
 * @author F.Ebrahimi
 * @since 2/5/2024
 */
@Aspect
@Order(20)
@Transactional
public class TrackerAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(TrackerAspect.class);

    private final TrackingDataProvider trackingDataProvider;

    private final AnnotationUtil annotationUtil;

    private final TrackerService trackerService;

    public TrackerAspect(TrackingDataProvider trackingDataProvider, AnnotationUtil annotationUtil, TrackerService trackerService) {
        this.trackingDataProvider = trackingDataProvider;
        this.annotationUtil = annotationUtil;
        this.trackerService = trackerService;
    }

    @Around(value = "@annotation(com.tosan.tools.tracker.starter.api.Tracking) ")
    public Object track(ProceedingJoinPoint pjp) throws Throwable {
        String serviceName = pjp.getSignature().getName();
        Object[] args = pjp.getArgs();
        String[] parameterNames = ((MethodSignature) pjp.getSignature()).getParameterNames();
        Tracking trackingAnnotation = annotationUtil.getAnnotation(pjp, Tracking.class);
        RequestTrackEntity requestTrack = trackingDataProvider.getRequestTrack(args, parameterNames);
        ServiceEntity service = trackingDataProvider.getService(serviceName);
        RequestTrackEntity resultRequestTrack =
                trackerService.trackBeforeService(args, parameterNames, service, requestTrack, trackingAnnotation);
        Object returnType = ((MethodSignature) pjp.getSignature()).getReturnType();
        if (Arrays.asList(((Class) returnType).getInterfaces()).contains(StreamResponse.class)) {
            return trackSseEmitter(pjp, requestTrack, trackingAnnotation);
        } else {
            return trackNormalService(pjp, resultRequestTrack, trackingAnnotation);
        }
    }

    private Object trackSseEmitter(ProceedingJoinPoint pjp, RequestTrackEntity requestTrack, Tracking trackingAnnotation)
            throws Throwable {
        Object proceed = pjp.proceed();
        ((StreamResponse) proceed)
                .doOnEach(responseDto -> trackAfterService(responseDto, requestTrack, trackingAnnotation));
        ((StreamResponse) proceed)
                .onError(throwable -> trackAfterException(requestTrack, throwable));
        return proceed;
    }

    private Object trackNormalService(ProceedingJoinPoint pjp, RequestTrackEntity requestTrack, Tracking trackingAnnotation)
            throws Throwable {
        try {
            Object proceed = pjp.proceed();
            trackAfterService(proceed, requestTrack, trackingAnnotation);
            return proceed;
        } catch (Throwable e) {
            trackAfterException(requestTrack, e);
            throw e;
        }
    }

    private void trackAfterException(RequestTrackEntity requestTrack, Throwable e) {
        try {
            ResponseTrackEntity responseTrack = trackingDataProvider.getExceptionTrack(e, requestTrack);
            trackerService.trackOnException(e, requestTrack, responseTrack);
        } catch (Exception ex) {
            LOGGER.error("error on exception tracking ", e);
        }
    }

    private void trackAfterService(Object result, RequestTrackEntity requestTrack, Tracking trackingAnnotation) {
        try {
            ResponseTrackEntity responseTrack = trackingDataProvider.getResponseTrack(result, requestTrack);
            if (responseTrack.getTrackType() != null && responseTrack.getTrackType().equals(TrackType.EXCEPTION)) {
                trackerService.trackOnStreamException(requestTrack, responseTrack);
            } else {
                trackerService.trackAfterService(result, requestTrack, trackingAnnotation, responseTrack);
            }
        } catch (Exception e) {
            LOGGER.error("error on response tracking ", e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy