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

org.opendaylight.netconf.test.tool.customrpc.RpcMapping Maven / Gradle / Ivy

There is a newer version: 8.0.1
Show newest version
/*
 * Copyright (c) 2016 Cisco Systems, Inc. and others.  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.netconf.test.tool.customrpc;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import javax.xml.bind.JAXB;
import org.opendaylight.netconf.api.DocumentedException;
import org.opendaylight.netconf.api.xml.XmlElement;
import org.opendaylight.netconf.api.xml.XmlUtil;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;

/**
 * Mapping between RPCs and responses.
 */
class RpcMapping {

    private final Multimap requestToResponseMap = ArrayListMultimap.create();

    /**
     * Creates new mapping from file.
     *
     * @param config config file
     */
    RpcMapping(final File config) {
        final Rpcs rpcs = JAXB.unmarshal(config, Rpcs.class);
        for (final Rpc rpc : rpcs.getRpcs()) {
            final Stream stream = rpc.getOutput().stream()
                    .map(XmlData::getData);
            final XmlElement element = XmlElement.fromDomDocument(rpc.getInput().getData());
            requestToResponseMap.putAll(new Request(element), stream::iterator);
        }
    }

    /**
     * Returns response matching given input. If multiple responses are configured for the same
     * request, every invocation of this method returns next response as they are defined in the config file.
     * Last configured response is used, when number of invocations is higher than number of configured responses
     * for rpc.
     *
     * @param input request
     * @return response document, or absent if mapping is not defined
     */
    Optional getResponse(final XmlElement input) {
        final Collection responses = requestToResponseMap.get(new Request(input));
        final Iterator iterator = responses.iterator();
        if (iterator.hasNext()) {
            final Document response = iterator.next();
            if (iterator.hasNext()) {
                iterator.remove();
            }
            return Optional.of(response);
        }
        return Optional.empty();
    }

    /**
     * Rpc input wrapper. Needed because of custom {@link Request#equals(Object)}
     * and {@link Request#hashCode()} implementations.
     */
    private static class Request {
        private final XmlElement xmlElement;
        private final int hashCode;

        Request(final XmlElement element) {
            this.xmlElement = element;
            hashCode = XmlUtil.toString(element)
                    .replaceAll("message-id=.*(>| )", "") //message id is variable, remove it
                    .replaceAll("\\s+", "") //remove whitespaces
                    .hashCode();
        }

        @Override
        public boolean equals(final Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            final Request request = (Request) obj;
            return documentEquals(this.xmlElement, request.xmlElement);
        }

        @Override
        public int hashCode() {
            return hashCode;
        }

        private static boolean documentEquals(final XmlElement e1, final XmlElement e2) {
            if (!e1.getNamespaceOptionally().equals(e2.getNamespaceOptionally())) {
                return false;
            }
            if (!e1.getName().equals(e2.getName())) {
                return false;
            }
            if (attributesNotEquals(e1, e2)) {
                return false;
            }

            final List e1Children = e1.getChildElements();
            final List e2Children = e2.getChildElements();
            if (e1Children.size() != e2Children.size()) {
                return false;
            }
            final Iterator e1Iterator = e1Children.iterator();
            final Iterator e2Iterator = e2Children.iterator();
            while (e1Iterator.hasNext() && e2Iterator.hasNext()) {
                if (!documentEquals(e1Iterator.next(), e2Iterator.next())) {
                    return false;
                }
            }

            if (e1Children.isEmpty() && e2Children.isEmpty()) {
                try {
                    return e1.getTextContent().equals(e2.getTextContent());
                } catch (final DocumentedException e) {
                    return false;
                }
            }
            return true;
        }

        private static boolean attributesNotEquals(final XmlElement e1, final XmlElement e2) {
            final Map e1Attrs = e1.getAttributes();
            final Map e2Attrs = e2.getAttributes();
            final Iterator> e1AttrIt = e1Attrs.entrySet().iterator();
            final Iterator> e2AttrIt = e2Attrs.entrySet().iterator();
            while (e1AttrIt.hasNext() && e2AttrIt.hasNext()) {
                final Map.Entry e1Next = e1AttrIt.next();
                final Map.Entry e2Next = e2AttrIt.next();
                if (e1Next.getKey().equals("message-id") && e2Next.getKey().equals("message-id")) {
                    continue;
                }
                if (e1Next.getKey().equals("xmlns") && e2Next.getKey().equals("xmlns")) {
                    continue;
                }
                if (!e1Next.getKey().equals(e2Next.getKey())) {
                    return true;
                }
                if (!e1Next.getValue().getValue().equals(e2Next.getValue().getValue())) {
                    return true;
                }
            }
            return false;
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy