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.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
19 import org.opendaylight.yangtools.yang.data.api.schema.stream.ReusableStreamReceiver;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNodes;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
25 import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataInput;
26 import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataOutput;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Utility serialization/deserialization for {@link DataTreeCandidate}. Note that this utility does not maintain
32 * before-image information across serialization.
34 * @author Robert Varga
37 public final class DataTreeCandidateInputOutput {
38 private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidateInputOutput.class);
39 private static final byte DELETE = 0;
40 private static final byte SUBTREE_MODIFIED = 1;
41 private static final byte UNMODIFIED = 2;
42 private static final byte WRITE = 3;
43 private static final byte APPEARED = 4;
44 private static final byte DISAPPEARED = 5;
46 private DataTreeCandidateInputOutput() {
47 throw new UnsupportedOperationException();
50 private static DataTreeCandidateNode readModifiedNode(final ModificationType type, final NormalizedNodeDataInput in,
51 final ReusableStreamReceiver receiver) throws IOException {
52 final PathArgument identifier = in.readPathArgument();
53 final Collection<DataTreeCandidateNode> children = readChildren(in, receiver);
54 if (children.isEmpty()) {
55 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
59 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
62 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in,
63 final ReusableStreamReceiver receiver) throws IOException {
64 final int size = in.readInt();
66 return ImmutableList.of();
69 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
70 for (int i = 0; i < size; ++i) {
71 final DataTreeCandidateNode child = readNode(in, receiver);
79 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in,
80 final ReusableStreamReceiver receiver) throws IOException {
81 final byte type = in.readByte();
84 return readModifiedNode(ModificationType.APPEARED, in, receiver);
86 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
88 return readModifiedNode(ModificationType.DISAPPEARED, in, receiver);
89 case SUBTREE_MODIFIED:
90 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in, receiver);
94 return DataTreeCandidateNodes.written(in.readNormalizedNode(receiver));
96 throw new IllegalArgumentException("Unhandled node type " + type);
100 public static DataTreeCandidate readDataTreeCandidate(final DataInput in, final ReusableStreamReceiver receiver)
102 final NormalizedNodeDataInput reader = NormalizedNodeDataInput.newDataInput(in);
103 final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
104 final byte type = reader.readByte();
106 final DataTreeCandidateNode rootNode;
109 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED,
110 readChildren(reader, receiver));
113 rootNode = DeletedDataTreeCandidateNode.create();
116 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED,
117 readChildren(reader, receiver));
119 case SUBTREE_MODIFIED:
120 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
121 readChildren(reader, receiver));
124 rootNode = DataTreeCandidateNodes.written(reader.readNormalizedNode(receiver));
127 rootNode = AbstractDataTreeCandidateNode.createUnmodified();
130 throw new IllegalArgumentException("Unhandled node type " + type);
133 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
136 private static void writeChildren(final NormalizedNodeDataOutput out,
137 final Collection<DataTreeCandidateNode> children) throws IOException {
138 out.writeInt(children.size());
139 for (DataTreeCandidateNode child : children) {
140 writeNode(out, child);
144 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
146 switch (node.getModificationType()) {
148 out.writeByte(APPEARED);
149 out.writePathArgument(node.getIdentifier());
150 writeChildren(out, node.getChildNodes());
153 out.writeByte(DELETE);
154 out.writePathArgument(node.getIdentifier());
157 out.writeByte(DISAPPEARED);
158 out.writePathArgument(node.getIdentifier());
159 writeChildren(out, node.getChildNodes());
161 case SUBTREE_MODIFIED:
162 out.writeByte(SUBTREE_MODIFIED);
163 out.writePathArgument(node.getIdentifier());
164 writeChildren(out, node.getChildNodes());
167 out.writeByte(WRITE);
168 out.writeNormalizedNode(node.getDataAfter().get());
171 out.writeByte(UNMODIFIED);
174 throwUnhandledNodeType(node);
178 public static void writeDataTreeCandidate(final DataOutput out, final DataTreeCandidate candidate)
180 try (NormalizedNodeDataOutput writer = PayloadVersion.current().getStreamVersion().newDataOutput(out)) {
181 writer.writeYangInstanceIdentifier(candidate.getRootPath());
183 final DataTreeCandidateNode node = candidate.getRootNode();
184 switch (node.getModificationType()) {
186 writer.writeByte(APPEARED);
187 writeChildren(writer, node.getChildNodes());
190 writer.writeByte(DELETE);
193 writer.writeByte(DISAPPEARED);
194 writeChildren(writer, node.getChildNodes());
196 case SUBTREE_MODIFIED:
197 writer.writeByte(SUBTREE_MODIFIED);
198 writeChildren(writer, node.getChildNodes());
201 writer.writeByte(UNMODIFIED);
204 writer.writeByte(WRITE);
205 writer.writeNormalizedNode(node.getDataAfter().get());
208 throwUnhandledNodeType(node);
213 private static void throwUnhandledNodeType(final DataTreeCandidateNode node) {
214 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());