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

org.opendaylight.jsonrpc.dom.codec.JsonRpcCodecFactory Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020 dNation.cloud. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.jsonrpc.dom.codec;

import com.google.common.annotations.Beta;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.dom.api.DOMNotification;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;

/**
 * Factory to create instances of various {@link Codec}s within given {@link EffectiveModelContext}. Created
 * {@link Codec} instances are cached for reuse and follow JSONRPC rule "be very tolerant at decoding, but be strict on
 * encoding" - which means that some JSON constructs differ from RFC7951. These differences are covered in
 * Application of YANG Modeling to JSON RPCs for
 * Interoperability Purposes.
 *
 * @author Richard Kosegi
 */
@Beta
public final class JsonRpcCodecFactory {
    private final EffectiveModelContext context;
    private final JsonRpcPathCodec pathCodec;

    private final LoadingCache dataCodecCache = CacheBuilder.newBuilder()
            .build(new CacheLoader() {
                @Override
                public DataCodec load(YangInstanceIdentifier path) throws Exception {
                    return new DataCodec(context, path);
                }
            });

    private final LoadingCache rpcCodecCache = CacheBuilder.newBuilder()
            .build(new CacheLoader() {
                @Override
                public RpcIoCodecHolder load(RpcDefinition path) throws Exception {
                    return new RpcIoCodecHolder(context, path);
                }
            });

    private final LoadingCache notifCodecCache = CacheBuilder.newBuilder()
            .build(new CacheLoader() {
                @Override
                public NotificationCodec load(NotificationDefinition definition) throws Exception {
                    return NotificationCodec.create(context, definition);
                }
            });

    public JsonRpcCodecFactory(EffectiveModelContext context) {
        this.context = Objects.requireNonNull(context);
        pathCodec = JsonRpcPathCodec.create(context);
    }

    /**
     * Get {@link Codec} for RPC input.
     *
     * @param definition {@link RpcDefinition}
     * @return RPC input codec
     */
    public Codec rpcInputCodec(@NonNull RpcDefinition definition) {
        Objects.requireNonNull(definition);
        return rpcCodecCache.getUnchecked(definition).input();
    }

    /**
     * Get {@link Codec} for RPC output.
     *
     * @param definition {@link RpcDefinition}
     * @return RPC input codec
     */
    public Codec rpcOutputCodec(@NonNull RpcDefinition definition) {
        return rpcCodecCache.getUnchecked(definition).output();
    }

    /**
     * Get {@link Codec} to translate between JSONRPC notification encoded as {@link JsonElement} and
     * {@link DOMNotification}.
     *
     * @param definition schema definition of notification
     * @return notification codec
     */
    public Codec notificationCodec(
            @NonNull NotificationDefinition definition) {
        Objects.requireNonNull(definition);
        return notifCodecCache.getUnchecked(definition);
    }

    /**
     * Get {@link Codec} to translate between JSONRPC path and {@link YangInstanceIdentifier}.
     *
     * @return path codec
     */
    public Codec pathCodec() {
        return pathCodec;
    }

    /**
     * Get {@link Codec} to translate between JSONRPC data and {@link NormalizedNode}s.
     *
     * @param path path within data tree
     * @return data codec
     */
    public Codec dataCodec(@NonNull YangInstanceIdentifier path) {
        Objects.requireNonNull(path);
        if (path.isEmpty()) {
            throw new IllegalArgumentException("Empty path is not supported by data codec");
        }
        return dataCodecCache.getUnchecked(path);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy