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.stream.ReusableStreamReceiver;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
27 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
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, final NormalizedNodeDataInput in,
52 final ReusableStreamReceiver receiver) throws IOException {
53 final PathArgument identifier = in.readPathArgument();
54 final Collection<DataTreeCandidateNode> children = readChildren(in, receiver);
55 if (children.isEmpty()) {
56 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
60 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
63 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in,
64 final ReusableStreamReceiver receiver) throws IOException {
65 final int size = in.readInt();
67 return ImmutableList.of();
70 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
71 for (int i = 0; i < size; ++i) {
72 final DataTreeCandidateNode child = readNode(in, receiver);
80 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in,
81 final ReusableStreamReceiver receiver) throws IOException {
82 final byte type = in.readByte();
85 return readModifiedNode(ModificationType.APPEARED, in, receiver);
87 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
89 return readModifiedNode(ModificationType.DISAPPEARED, in, receiver);
90 case SUBTREE_MODIFIED:
91 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in, receiver);
95 return DataTreeCandidateNodes.written(in.readNormalizedNode(receiver));
97 throw new IllegalArgumentException("Unhandled node type " + type);
101 public static DataTreeCandidate readDataTreeCandidate(final DataInput in, final ReusableStreamReceiver receiver)
103 final NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(in);
104 final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
105 final byte type = reader.readByte();
107 final DataTreeCandidateNode rootNode;
110 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED,
111 readChildren(reader, receiver));
114 rootNode = DeletedDataTreeCandidateNode.create();
117 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED,
118 readChildren(reader, receiver));
120 case SUBTREE_MODIFIED:
121 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
122 readChildren(reader, receiver));
125 rootNode = DataTreeCandidateNodes.written(reader.readNormalizedNode(receiver));
128 rootNode = AbstractDataTreeCandidateNode.createUnmodified();
131 throw new IllegalArgumentException("Unhandled node type " + type);
134 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
137 private static void writeChildren(final NormalizedNodeDataOutput out,
138 final Collection<DataTreeCandidateNode> children) throws IOException {
139 out.writeInt(children.size());
140 for (DataTreeCandidateNode child : children) {
141 writeNode(out, child);
145 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
147 switch (node.getModificationType()) {
149 out.writeByte(APPEARED);
150 out.writePathArgument(node.getIdentifier());
151 writeChildren(out, node.getChildNodes());
154 out.writeByte(DELETE);
155 out.writePathArgument(node.getIdentifier());
158 out.writeByte(DISAPPEARED);
159 out.writePathArgument(node.getIdentifier());
160 writeChildren(out, node.getChildNodes());
162 case SUBTREE_MODIFIED:
163 out.writeByte(SUBTREE_MODIFIED);
164 out.writePathArgument(node.getIdentifier());
165 writeChildren(out, node.getChildNodes());
168 out.writeByte(WRITE);
169 out.writeNormalizedNode(node.getDataAfter().get());
172 out.writeByte(UNMODIFIED);
175 throwUnhandledNodeType(node);
179 public static void writeDataTreeCandidate(final DataOutput out, final DataTreeCandidate candidate)
181 try (NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out,
182 PayloadVersion.current().getStreamVersion())) {
183 writer.writeYangInstanceIdentifier(candidate.getRootPath());
185 final DataTreeCandidateNode node = candidate.getRootNode();
186 switch (node.getModificationType()) {
188 writer.writeByte(APPEARED);
189 writeChildren(writer, node.getChildNodes());
192 writer.writeByte(DELETE);
195 writer.writeByte(DISAPPEARED);
196 writeChildren(writer, node.getChildNodes());
198 case SUBTREE_MODIFIED:
199 writer.writeByte(SUBTREE_MODIFIED);
200 writeChildren(writer, node.getChildNodes());
203 writer.writeByte(UNMODIFIED);
206 writer.writeByte(WRITE);
207 writer.writeNormalizedNode(node.getDataAfter().get());
210 throwUnhandledNodeType(node);
215 private static void throwUnhandledNodeType(final DataTreeCandidateNode node) {
216 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());