X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-clustering-commons%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Fnode%2Futils%2Fstream%2FNormalizedNodeOutputStreamWriter.java;h=34debfda13033b63bd62846b7f080bf0a4ad9979;hp=08567fd79ee9e4980dc6a359ae6fab422040b03d;hb=4a05f2e08a30bb7834139b0e4ed40e1b4fbf6d82;hpb=b3bf00226d83387a060d97a4f573377f07e93b5a diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeOutputStreamWriter.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeOutputStreamWriter.java index 08567fd79e..34debfda13 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeOutputStreamWriter.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeOutputStreamWriter.java @@ -1,342 +1,81 @@ /* + * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. * - * Copyright (c) 2014 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 - * + * 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.controller.cluster.datastore.node.utils.stream; import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; -import java.util.Set; +import org.opendaylight.yangtools.yang.common.QName; /** * NormalizedNodeOutputStreamWriter will be used by distributed datastore to send normalized node in * a stream. * A stream writer wrapper around this class will write node objects to stream in recursive manner. * for example - If you have a ContainerNode which has a two LeafNode as children, then - * you will first call {@link #startContainerNode(YangInstanceIdentifier.NodeIdentifier, int)}, then will call - * {@link #leafNode(YangInstanceIdentifier.NodeIdentifier, Object)} twice and then, {@link #endNode()} to end - * container node. + * you will first call + * {@link #startContainerNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, int)}, + * then will call + * {@link #leafNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, Object)} twice + * and then, {@link #endNode()} to end container node. * * Based on the each node, the node type is also written to the stream, that helps in reconstructing the object, * while reading. - * - * */ - -public class NormalizedNodeOutputStreamWriter implements NormalizedNodeStreamWriter{ - - private static final Logger LOG = LoggerFactory.getLogger(NormalizedNodeOutputStreamWriter.class); - - private final DataOutputStream writer; - +public class NormalizedNodeOutputStreamWriter extends AbstractNormalizedNodeDataOutput { private final Map stringCodeMap = new HashMap<>(); - public NormalizedNodeOutputStreamWriter(OutputStream stream) throws IOException { - Preconditions.checkNotNull(stream); - writer = new DataOutputStream(stream); - } - - @Override - public void leafNode(YangInstanceIdentifier.NodeIdentifier name, Object value) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Writing a new leaf node"); - startNode(name.getNodeType(), NodeTypes.LEAF_NODE); - - writeObject(value); - } - - @Override - public void startLeafSet(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new leaf set"); - - startNode(name.getNodeType(), NodeTypes.LEAF_SET); - } - - @Override - public void leafSetEntryNode(Object value) throws IOException, IllegalArgumentException { - LOG.debug("Writing a new leaf set entry node"); - - writer.writeByte(NodeTypes.LEAF_SET_ENTRY_NODE); - writeObject(value); - } - - @Override - public void startContainerNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - - LOG.debug("Starting a new container node"); - - startNode(name.getNodeType(), NodeTypes.CONTAINER_NODE); - } - - @Override - public void startUnkeyedList(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new unkeyed list"); - - startNode(name.getNodeType(), NodeTypes.UNKEYED_LIST); - } - - @Override - public void startUnkeyedListItem(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalStateException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new unkeyed list item"); - - startNode(name.getNodeType(), NodeTypes.UNKEYED_LIST_ITEM); - } - - @Override - public void startMapNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new map node"); - - startNode(name.getNodeType(), NodeTypes.MAP_NODE); - } - - @Override - public void startMapEntryNode(YangInstanceIdentifier.NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(identifier, "Node identifier should not be null"); - LOG.debug("Starting a new map entry node"); - startNode(identifier.getNodeType(), NodeTypes.MAP_ENTRY_NODE); - - writeKeyValueMap(identifier.getKeyValues()); - - } - - @Override - public void startOrderedMapNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new ordered map node"); - - startNode(name.getNodeType(), NodeTypes.ORDERED_MAP_NODE); - } - - @Override - public void startChoiceNode(YangInstanceIdentifier.NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Starting a new choice node"); - - startNode(name.getNodeType(), NodeTypes.CHOICE_NODE); - } - - @Override - public void startAugmentationNode(YangInstanceIdentifier.AugmentationIdentifier identifier) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(identifier, "Node identifier should not be null"); - LOG.debug("Starting a new augmentation node"); - - writer.writeByte(NodeTypes.AUGMENTATION_NODE); - writeQNameSet(identifier.getPossibleChildNames()); + /** + * @deprecated Use {@link #NormalizedNodeOutputStreamWriter(DataOutput)} instead. + */ + @Deprecated + public NormalizedNodeOutputStreamWriter(final OutputStream stream) throws IOException { + this((DataOutput) new DataOutputStream(Preconditions.checkNotNull(stream))); } - @Override - public void anyxmlNode(YangInstanceIdentifier.NodeIdentifier name, Object value) throws IOException, IllegalArgumentException { - Preconditions.checkNotNull(name, "Node identifier should not be null"); - LOG.debug("Writing a new xml node"); - - startNode(name.getNodeType(), NodeTypes.ANY_XML_NODE); - - writeObject(value); + /** + * @deprecated Use {@link NormalizedNodeInputOutput#newDataOutput(DataOutput)} instead. + */ + @Deprecated + public NormalizedNodeOutputStreamWriter(final DataOutput output) { + super(output); } @Override - public void endNode() throws IOException, IllegalStateException { - LOG.debug("Ending the node"); - - writer.writeByte(NodeTypes.END_NODE); + protected final short streamVersion() { + return TokenTypes.LITHIUM_VERSION; } @Override - public void close() throws IOException { - writer.close(); + protected void writeQName(final QName qname) throws IOException { + writeString(qname.getLocalName()); + writeString(qname.getNamespace().toString()); + writeString(qname.getFormattedRevision()); } @Override - public void flush() throws IOException { - writer.flush(); - } - - private void startNode(final QName qName, byte nodeType) throws IOException { - - Preconditions.checkNotNull(qName, "QName of node identifier should not be null."); - // First write the type of node - writer.writeByte(nodeType); - // Write Start Tag - writeQName(qName); - } - - private void writeQName(QName qName) throws IOException { - - writeCodedString(qName.getLocalName()); - writeCodedString(qName.getNamespace().toString()); - writeCodedString(qName.getFormattedRevision()); - } - - private void writeCodedString(String key) throws IOException { - Integer value = stringCodeMap.get(key); - - if(value != null) { - writer.writeBoolean(true); - writer.writeInt(value); - } else { - if(key != null) { - stringCodeMap.put(key, Integer.valueOf(stringCodeMap.size())); - } - writer.writeBoolean(false); - writer.writeUTF(key); - } - } - - private void writeObjSet(Set set) throws IOException { - if(!set.isEmpty()){ - writer.writeInt(set.size()); - for(Object o : set){ - if(o instanceof String){ - writeCodedString(o.toString()); - } else { - throw new IllegalArgumentException("Expected value type to be String but was : " + - o.toString()); - } - } - } else { - writer.writeInt(0); - } - } - - private void writeYangInstanceIdentifier(YangInstanceIdentifier identifier) throws IOException { - Iterable pathArguments = identifier.getPathArguments(); - int size = Iterables.size(pathArguments); - writer.writeInt(size); - - for(YangInstanceIdentifier.PathArgument pathArgument : pathArguments) { - writePathArgument(pathArgument); - } - } - - private void writePathArgument(YangInstanceIdentifier.PathArgument pathArgument) throws IOException { - - byte type = PathArgumentTypes.getSerializablePathArgumentType(pathArgument); - - writer.writeByte(type); - - switch(type) { - case PathArgumentTypes.NODE_IDENTIFIER : - - YangInstanceIdentifier.NodeIdentifier nodeIdentifier = - (YangInstanceIdentifier.NodeIdentifier) pathArgument; - - writeQName(nodeIdentifier.getNodeType()); - break; - - case PathArgumentTypes.NODE_IDENTIFIER_WITH_PREDICATES: - - YangInstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifierWithPredicates = - (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument; - writeQName(nodeIdentifierWithPredicates.getNodeType()); - - writeKeyValueMap(nodeIdentifierWithPredicates.getKeyValues()); - break; - - case PathArgumentTypes.NODE_IDENTIFIER_WITH_VALUE : - - YangInstanceIdentifier.NodeWithValue nodeWithValue = - (YangInstanceIdentifier.NodeWithValue) pathArgument; - - writeQName(nodeWithValue.getNodeType()); - writeObject(nodeWithValue.getValue()); - break; - - case PathArgumentTypes.AUGMENTATION_IDENTIFIER : - - YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifier = - (YangInstanceIdentifier.AugmentationIdentifier) pathArgument; - - // No Qname in augmentation identifier - writeQNameSet(augmentationIdentifier.getPossibleChildNames()); - break; - default : - throw new IllegalStateException("Unknown node identifier type is found : " + pathArgument.getClass().toString() ); - } - } - - private void writeKeyValueMap(Map keyValueMap) throws IOException { - if(keyValueMap != null && !keyValueMap.isEmpty()) { - writer.writeInt(keyValueMap.size()); - Set qNameSet = keyValueMap.keySet(); - - for(QName qName : qNameSet) { - writeQName(qName); - writeObject(keyValueMap.get(qName)); - } - } else { - writer.writeInt(0); - } - } - - private void writeQNameSet(Set children) throws IOException { - // Write each child's qname separately, if list is empty send count as 0 - if(children != null && !children.isEmpty()) { - writer.writeInt(children.size()); - for(QName qName : children) { - writeQName(qName); + protected void writeString(final String string) throws IOException { + if (string != null) { + final Integer value = stringCodeMap.get(string); + if (value == null) { + stringCodeMap.put(string, stringCodeMap.size()); + writeByte(TokenTypes.IS_STRING_VALUE); + writeUTF(string); + } else { + writeByte(TokenTypes.IS_CODE_VALUE); + writeInt(value); } } else { - LOG.debug("augmentation node does not have any child"); - writer.writeInt(0); - } - } - - private void writeObject(Object value) throws IOException { - - byte type = ValueTypes.getSerializableType(value); - // Write object type first - writer.writeByte(type); - - switch(type) { - case ValueTypes.BOOL_TYPE: - writer.writeBoolean((Boolean) value); - break; - case ValueTypes.QNAME_TYPE: - writeQName((QName) value); - break; - case ValueTypes.INT_TYPE: - writer.writeInt((Integer) value); - break; - case ValueTypes.BYTE_TYPE: - writer.writeByte((Byte) value); - break; - case ValueTypes.LONG_TYPE: - writer.writeLong((Long) value); - break; - case ValueTypes.SHORT_TYPE: - writer.writeShort((Short) value); - break; - case ValueTypes.BITS_TYPE: - writeObjSet((Set) value); - break; - case ValueTypes.YANG_IDENTIFIER_TYPE: - writeYangInstanceIdentifier((YangInstanceIdentifier) value); - break; - default: - writer.writeUTF(value.toString()); - break; + writeByte(TokenTypes.IS_NULL_VALUE); } } }