package io.muoncore.spring; import io.muoncore.Muon; import io.muoncore.ServiceDescriptor; import io.muoncore.exception.MuonException; import io.muoncore.spring.annotations.EventSourceListener; import io.muoncore.spring.annotations.MuonController; import io.muoncore.spring.annotations.MuonRequestListener; import io.muoncore.spring.annotations.MuonStreamListener; import io.muoncore.spring.mapping.MuonRequestListenerService; import io.muoncore.spring.mapping.MuonStreamSubscriptionService; import io.muoncore.spring.methodinvocation.MuonRequestMethodInvocation; import io.muoncore.spring.methodinvocation.MuonStreamMethodInvocation; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.StringValueResolver; import java.lang.reflect.Method; import java.util.Optional; public class MuonControllerBeanPostProcessor implements BeanPostProcessor, EmbeddedValueResolverAware { @Autowired private MuonStreamSubscriptionService streamSubscrioptionService; @Autowired private MuonRequestListenerService muonRequestListenerService; private StringValueResolver resolver; @Autowired private Muon muon; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean == null) { return null; } Class beanClazz = bean.getClass(); MuonController annotation = AnnotationUtils.findAnnotation(beanClazz, MuonController.class); if (annotation == null) { return bean; } try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } for (Method method : beanClazz.getMethods()) { MuonStreamListener muonStreamListener = AnnotationUtils.findAnnotation(method, MuonStreamListener.class); if (muonStreamListener != null) { streamSubscrioptionService.setupMuonMapping(resolver.resolveStringValue(muonStreamListener.url()), new MuonStreamMethodInvocation(method, bean)); } MuonRequestListener muonQueryListener = AnnotationUtils.findAnnotation(method, MuonRequestListener.class); if (muonQueryListener != null) { muonRequestListenerService.addRequestMapping(resolver.resolveStringValue(muonQueryListener.path()), new MuonRequestMethodInvocation(method, bean)); } EventSourceListener eventSourceListener = AnnotationUtils.findAnnotation(method, EventSourceListener.class); if (eventSourceListener != null) { Optional<ServiceDescriptor> svc = muon.getDiscovery().findService(service -> service.getTags().contains("eventstore")); svc.orElseThrow(() -> new MuonException("Unable to locate an event store in the current distributed system")); svc.ifPresent(service -> streamSubscrioptionService.setupMuonMapping(resolver.resolveStringValue( "stream://" + service.getIdentifier() + "/" + eventSourceListener.stream()), new MuonStreamMethodInvocation(method, bean))); } } return bean; } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this.resolver = resolver; } }