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

org.iris_events.asyncapi.runtime.client.ClientDefinitionMerger Maven / Gradle / Ivy

There is a newer version: 6.1.8
Show newest version
package org.iris_events.asyncapi.runtime.client;

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

import org.iris_events.asyncapi.api.AsyncApiConstants;
import org.iris_events.asyncapi.runtime.json.IrisObjectMapper;
import org.iris_events.asyncapi.runtime.scanner.model.ClientDefinitions;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;

public class ClientDefinitionMerger {

    public JsonNode merge(List definitions, String version) {
        JsonNode clientAsyncApi = generateBase(version);

        definitions.forEach(def -> {
            setChannelNodes(clientAsyncApi, def);
            setSchemaNodes(clientAsyncApi, def);
        });

        return clientAsyncApi;
    }

    private void nestSchemas(Map schemasNodes, String serviceName) {
        schemasNodes.entrySet().stream()
                .filter(stringJsonNodeEntry -> stringJsonNodeEntry.getValue() != null)
                .forEach(stringJsonNodeEntry -> setServiceSpecificRefs(serviceName, stringJsonNodeEntry));
    }

    private void setServiceSpecificRefs(String serviceName, Map.Entry stringJsonNodeEntry) {
        stringJsonNodeEntry.getValue().findValues(AsyncApiConstants.REF_NODE).forEach(refNode -> {
            if (refNode instanceof TextNode) {
                try {
                    // Stupid immutable text node...
                    Field f = TextNode.class.getDeclaredField("_value");
                    f.setAccessible(true);
                    f.set(refNode, insertServiceName(refNode.asText(), serviceName));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    private String insertServiceName(String existingRefValue, String serviceName) {
        String newRefPrefix = AsyncApiConstants.COMPONENT_SCHEMAS_PREFIX + serviceName + "/";
        return existingRefValue.replace(AsyncApiConstants.COMPONENT_SCHEMAS_PREFIX, newRefPrefix);
    }

    private JsonNode generateBase(String version) {
        ObjectMapper objectMapper = IrisObjectMapper.getObjectMapper();
        ObjectNode root = objectMapper.createObjectNode();

        root.put("asyncapi", "2.0.0");
        // TODO: opensource - make it configurable
        root.put("id", "urn:org:iris_events:client-api");

        ObjectNode infoNode = objectMapper.createObjectNode();
        infoNode.put("title", "Iris Client API");
        infoNode.put("version", version);

        root.set("info", infoNode);
        root.set("channels", objectMapper.createObjectNode());

        ObjectNode componentsNode = objectMapper.createObjectNode();
        componentsNode.set("schemas", objectMapper.createObjectNode());

        root.set("components", componentsNode);

        return root;
    }

    private void setSchemaNodes(JsonNode clientAsyncApi, ClientDefinitions definitions) {
        nestSchemas(definitions.getSchemasNodes(), definitions.getServiceName());
        ObjectNode schemasNode = (ObjectNode) ((ObjectNode) clientAsyncApi.findPath(AsyncApiConstants.COMPONENTS_NODE)
                .findPath(AsyncApiConstants.SCHEMAS_NODE)).set(
                        definitions.getServiceName(), IrisObjectMapper.getObjectMapper().createObjectNode())
                .findPath(definitions.getServiceName());
        definitions.getSchemasNodes().forEach(schemasNode::set);
    }

    private void setChannelNodes(JsonNode clientAsyncApi, ClientDefinitions definitions) {
        nestSchemas(definitions.getClientChannelNodes(),
                definitions.getServiceName());
        ObjectNode channelsNode = (ObjectNode) clientAsyncApi.findPath(AsyncApiConstants.CHANNELS_NODE);
        definitions.getClientChannelNodes().forEach(channelsNode::set);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy