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

net.n2oapp.framework.boot.stomp.N2oWebSocketController Maven / Gradle / Ivy

There is a newer version: 7.28.2
Show newest version
package net.n2oapp.framework.boot.stomp;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.n2oapp.framework.api.MetadataEnvironment;
import net.n2oapp.framework.api.StringUtils;
import net.n2oapp.framework.api.metadata.action.N2oAction;
import net.n2oapp.framework.api.metadata.application.N2oApplication;
import net.n2oapp.framework.api.metadata.compile.CompileProcessor;
import net.n2oapp.framework.api.metadata.event.N2oAbstractEvent;
import net.n2oapp.framework.api.metadata.event.N2oStompEvent;
import net.n2oapp.framework.api.metadata.meta.action.AbstractAction;
import net.n2oapp.framework.api.metadata.pipeline.ReadPipeline;
import net.n2oapp.framework.api.register.SourceInfo;
import net.n2oapp.framework.config.metadata.compile.N2oCompileProcessor;
import net.n2oapp.framework.config.register.route.RouteUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;

import java.util.List;
import java.util.Map;

/**
 * Реализация контроллера для отправки сообщений по web-socket
 */
public class N2oWebSocketController implements WebSocketController {

    private static final String APPLICATION_DEFAULT_NAME = "default";
    private ReadPipeline pipeline;
    private MetadataEnvironment environment;
    private ObjectMapper mapper;
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    public N2oWebSocketController(ReadPipeline pipeline, MetadataEnvironment environment, ObjectMapper mapper) {
        this.pipeline = pipeline;
        this.environment = environment;
        this.mapper = mapper;
    }

    public void setPipeline(ReadPipeline pipeline) {
        this.pipeline = pipeline;
    }

    public void setEnvironment(MetadataEnvironment environment) {
        this.environment = environment;
    }

    @Override
    public void convertAndSend(String destination, Object message) {
        destination = RouteUtil.normalize(destination);
        messagingTemplate.convertAndSend(destination, initAction(destination, message));
    }


    @Override
    public void convertAndSendToUser(String user, String destination, Object message) {
        destination = RouteUtil.normalize(destination);
        messagingTemplate.convertAndSendToUser(user, destination, initAction(destination, message));
    }

    private  AbstractAction initAction(String destination, Object message) {
        N2oApplication application = getSourceApplication();
        N2oAction stompAction = getStompAction(destination, application);
        CompileProcessor p = new N2oCompileProcessor(environment);
        return p.compile(resolveLinks(stompAction, message), null);
    }

    private Object resolveLinks(Object stompAction, Object message) {
        Map sourceMap = mapper.convertValue(stompAction, Map.class);
        Map messageActionMap = mapper.convertValue(message, Map.class);
        for (Map.Entry attr : sourceMap.entrySet()) {
            if (StringUtils.isLink(attr.getValue())) {
                String text = StringUtils.unwrapLink(attr.getValue());
                sourceMap.put(attr.getKey(), messageActionMap.get(text) != null ? messageActionMap.get(text).toString() : null);
            }
        }
        return mapper.convertValue(sourceMap, stompAction.getClass());
    }

    private N2oAction getStompAction(String destination, N2oApplication application) {
        if (destination == null)
            throw new N2oStompException("Не указано место назначения");
        if (application.getEvents() == null)
            throw new N2oStompException("В метаданной приложения не найдены события");
        for (N2oAbstractEvent event : application.getEvents()) {
            if (event instanceof N2oStompEvent && destination.equals(((N2oStompEvent) event).getDestination()))
                return ((N2oStompEvent) event).getAction();
        }
        throw new N2oStompException(String.format("В метаданной приложения не найдены события с указанным местом назначения %s", destination));
    }

    private N2oApplication getSourceApplication() {
        return pipeline.read().get(getApplicationId(environment), N2oApplication.class);
    }

    private String getApplicationId(MetadataEnvironment environment) {
        List sourceInfos = environment.getMetadataRegister().find(N2oApplication.class);
        if (sourceInfos == null || sourceInfos.isEmpty())
            return APPLICATION_DEFAULT_NAME;
        return sourceInfos.stream()
                .map(SourceInfo::getId)
                .filter(s -> !APPLICATION_DEFAULT_NAME.equals(s)).findFirst().orElse(APPLICATION_DEFAULT_NAME);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy