2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.datastore.persisted;
10 import com.google.common.annotations.Beta;
11 import com.google.common.collect.ImmutableList;
12 import java.io.DataInput;
13 import java.io.DataOutput;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput;
18 import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput;
19 import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ReusableImmutableNormalizedNodeStreamWriter;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Utility serialization/deserialization for {@link DataTreeCandidate}. Note that this utility does not maintain
33 * before-image information across serialization.
35 * @author Robert Varga
38 public final class DataTreeCandidateInputOutput {
39 private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidateInputOutput.class);
40 private static final byte DELETE = 0;
41 private static final byte SUBTREE_MODIFIED = 1;
42 private static final byte UNMODIFIED = 2;
43 private static final byte WRITE = 3;
44 private static final byte APPEARED = 4;
45 private static final byte DISAPPEARED = 5;
47 private DataTreeCandidateInputOutput() {
48 throw new UnsupportedOperationException();
51 private static DataTreeCandidateNode readModifiedNode(final ModificationType type,
52 final NormalizedNodeDataInput in, final ReusableImmutableNormalizedNodeStreamWriter writer)
55 final PathArgument identifier = in.readPathArgument();
56 final Collection<DataTreeCandidateNode> children = readChildren(in, writer);
57 if (children.isEmpty()) {
58 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
62 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
65 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in,
66 final ReusableImmutableNormalizedNodeStreamWriter writer) throws IOException {
67 final int size = in.readInt();
69 return ImmutableList.of();
72 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
73 for (int i = 0; i < size; ++i) {
74 final DataTreeCandidateNode child = readNode(in, writer);
82 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in,
83 final ReusableImmutableNormalizedNodeStreamWriter writer) throws IOException {
84 final byte type = in.readByte();
87 return readModifiedNode(ModificationType.APPEARED, in, writer);
89 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
91 return readModifiedNode(ModificationType.DISAPPEARED, in, writer);
92 case SUBTREE_MODIFIED:
93 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in, writer);
97 return DataTreeCandidateNodes.written(in.readNormalizedNode(writer));
99 throw new IllegalArgumentException("Unhandled node type " + type);
103 public static DataTreeCandidate readDataTreeCandidate(final DataInput in,
104 final ReusableImmutableNormalizedNodeStreamWriter writer) throws IOException {
105 final NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(in);
106 final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
107 final byte type = reader.readByte();
109 final DataTreeCandidateNode rootNode;
112 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED,
113 readChildren(reader, writer));
116 rootNode = DeletedDataTreeCandidateNode.create();
119 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED,
120 readChildren(reader, writer));
122 case SUBTREE_MODIFIED:
123 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
124 readChildren(reader, writer));
127 rootNode = DataTreeCandidateNodes.written(reader.readNormalizedNode(writer));
130 rootNode = AbstractDataTreeCandidateNode.createUnmodified();
133 throw new IllegalArgumentException("Unhandled node type " + type);
136 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
139 private static void writeChildren(final NormalizedNodeDataOutput out,
140 final Collection<DataTreeCandidateNode> children) throws IOException {
141 out.writeInt(children.size());
142 for (DataTreeCandidateNode child : children) {
143 writeNode(out, child);
147 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
149 switch (node.getModificationType()) {
151 out.writeByte(APPEARED);
152 out.writePathArgument(node.getIdentifier());
153 writeChildren(out, node.getChildNodes());
156 out.writeByte(DELETE);
157 out.writePathArgument(node.getIdentifier());
160 out.writeByte(DISAPPEARED);
161 out.writePathArgument(node.getIdentifier());
162 writeChildren(out, node.getChildNodes());
164 case SUBTREE_MODIFIED:
165 out.writeByte(SUBTREE_MODIFIED);
166 out.writePathArgument(node.getIdentifier());
167 writeChildren(out, node.getChildNodes());
170 out.writeByte(WRITE);
171 out.writeNormalizedNode(node.getDataAfter().get());
174 out.writeByte(UNMODIFIED);
177 throwUnhandledNodeType(node);
181 public static void writeDataTreeCandidate(final DataOutput out, final DataTreeCandidate candidate)
183 try (NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out,
184 PayloadVersion.current().getStreamVersion())) {
185 writer.writeYangInstanceIdentifier(candidate.getRootPath());
187 final DataTreeCandidateNode node = candidate.getRootNode();
188 switch (node.getModificationType()) {
190 writer.writeByte(APPEARED);
191 writeChildren(writer, node.getChildNodes());
194 writer.writeByte(DELETE);
197 writer.writeByte(DISAPPEARED);
198 writeChildren(writer, node.getChildNodes());
200 case SUBTREE_MODIFIED:
201 writer.writeByte(SUBTREE_MODIFIED);
202 writeChildren(writer, node.getChildNodes());
205 writer.writeByte(UNMODIFIED);
208 writer.writeByte(WRITE);
209 writer.writeNormalizedNode(node.getDataAfter().get());
212 throwUnhandledNodeType(node);
217 private static void throwUnhandledNodeType(final DataTreeCandidateNode node) {
218 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());