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 java.io.DataInput;
12 import java.io.DataOutput;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
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.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,
51 final NormalizedNodeDataInput in) throws IOException {
53 final PathArgument identifier = in.readPathArgument();
54 final Collection<DataTreeCandidateNode> children = readChildren(in);
55 if (children.isEmpty()) {
56 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
59 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
63 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in) throws IOException {
64 final int size = in.readInt();
66 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
67 for (int i = 0; i < size; ++i) {
68 final DataTreeCandidateNode child = readNode(in);
75 return Collections.emptyList();
79 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in) throws IOException {
80 final byte type = in.readByte();
83 return readModifiedNode(ModificationType.APPEARED, in);
85 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
87 return readModifiedNode(ModificationType.DISAPPEARED, in);
88 case SUBTREE_MODIFIED:
89 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in);
93 return DataTreeCandidateNodes.fromNormalizedNode(in.readNormalizedNode());
95 throw new IllegalArgumentException("Unhandled node type " + type);
99 public static DataTreeCandidate readDataTreeCandidate(final DataInput in) throws IOException {
100 final NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(in);
101 final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
102 final byte type = reader.readByte();
104 final DataTreeCandidateNode rootNode;
107 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED, readChildren(reader));
110 rootNode = DeletedDataTreeCandidateNode.create();
113 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED, readChildren(reader));
115 case SUBTREE_MODIFIED:
116 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
117 readChildren(reader));
120 rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
123 rootNode = AbstractDataTreeCandidateNode.createUnmodified();
126 throw new IllegalArgumentException("Unhandled node type " + type);
129 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
133 private static void writeChildren(final NormalizedNodeDataOutput out,
134 final Collection<DataTreeCandidateNode> children) throws IOException {
135 out.writeInt(children.size());
136 for (DataTreeCandidateNode child : children) {
137 writeNode(out, child);
141 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
143 switch (node.getModificationType()) {
145 out.writeByte(APPEARED);
146 out.writePathArgument(node.getIdentifier());
147 writeChildren(out, node.getChildNodes());
150 out.writeByte(DELETE);
151 out.writePathArgument(node.getIdentifier());
154 out.writeByte(DISAPPEARED);
155 out.writePathArgument(node.getIdentifier());
156 writeChildren(out, node.getChildNodes());
158 case SUBTREE_MODIFIED:
159 out.writeByte(SUBTREE_MODIFIED);
160 out.writePathArgument(node.getIdentifier());
161 writeChildren(out, node.getChildNodes());
164 out.writeByte(WRITE);
165 out.writeNormalizedNode(node.getDataAfter().get());
168 out.writeByte(UNMODIFIED);
171 throwUnhandledNodeType(node);
175 public static void writeDataTreeCandidate(final DataOutput out, DataTreeCandidate candidate) throws IOException {
176 try (NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out)) {
177 writer.writeYangInstanceIdentifier(candidate.getRootPath());
179 final DataTreeCandidateNode node = candidate.getRootNode();
180 switch (node.getModificationType()) {
182 writer.writeByte(APPEARED);
183 writeChildren(writer, node.getChildNodes());
186 writer.writeByte(DELETE);
189 writer.writeByte(DISAPPEARED);
190 writeChildren(writer, node.getChildNodes());
192 case SUBTREE_MODIFIED:
193 writer.writeByte(SUBTREE_MODIFIED);
194 writeChildren(writer, node.getChildNodes());
197 writer.writeByte(UNMODIFIED);
200 writer.writeByte(WRITE);
201 writer.writeNormalizedNode(node.getDataAfter().get());
204 throwUnhandledNodeType(node);
209 private static void throwUnhandledNodeType(final DataTreeCandidateNode node) {
210 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());