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.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputStreamReader;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
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,
52 final NormalizedNodeDataInput in) throws IOException {
54 final PathArgument identifier = in.readPathArgument();
55 final Collection<DataTreeCandidateNode> children = readChildren(in);
56 if (children.isEmpty()) {
57 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
60 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
64 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in) throws IOException {
65 final int size = in.readInt();
67 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
68 for (int i = 0; i < size; ++i) {
69 final DataTreeCandidateNode child = readNode(in);
76 return Collections.emptyList();
80 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in) throws IOException {
81 final byte type = in.readByte();
84 return readModifiedNode(ModificationType.APPEARED, in);
86 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
88 return readModifiedNode(ModificationType.DISAPPEARED, in);
89 case SUBTREE_MODIFIED:
90 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in);
94 return DataTreeCandidateNodes.fromNormalizedNode(in.readNormalizedNode());
96 throw new IllegalArgumentException("Unhandled node type " + type);
100 public static DataTreeCandidate readDataTreeCandidate(final DataInput in) throws IOException {
101 final NormalizedNodeDataInput reader = new NormalizedNodeInputStreamReader(in);
102 final YangInstanceIdentifier rootPath = reader.readYangInstanceIdentifier();
103 final byte type = reader.readByte();
105 final DataTreeCandidateNode rootNode;
108 rootNode = DeletedDataTreeCandidateNode.create();
110 case SUBTREE_MODIFIED:
111 rootNode = ModifiedDataTreeCandidateNode.create(readChildren(reader));
114 rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
117 throw new IllegalArgumentException("Unhandled node type " + type);
120 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
124 private static void writeChildren(final NormalizedNodeDataOutput out,
125 final Collection<DataTreeCandidateNode> children) throws IOException {
126 out.writeInt(children.size());
127 for (DataTreeCandidateNode child : children) {
128 writeNode(out, child);
132 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
134 switch (node.getModificationType()) {
136 out.writeByte(APPEARED);
137 out.writePathArgument(node.getIdentifier());
138 writeChildren(out, node.getChildNodes());
141 out.writeByte(DELETE);
142 out.writePathArgument(node.getIdentifier());
145 out.writeByte(DISAPPEARED);
146 out.writePathArgument(node.getIdentifier());
147 writeChildren(out, node.getChildNodes());
149 case SUBTREE_MODIFIED:
150 out.writeByte(SUBTREE_MODIFIED);
151 out.writePathArgument(node.getIdentifier());
152 writeChildren(out, node.getChildNodes());
155 out.writeByte(WRITE);
156 out.writeNormalizedNode(node.getDataAfter().get());
159 out.writeByte(UNMODIFIED);
162 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());
166 public static void writeDataTreeCandidate(final DataOutput out, DataTreeCandidate candidate) throws IOException {
167 try (final NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out)) {
168 writer.writeYangInstanceIdentifier(candidate.getRootPath());
170 final DataTreeCandidateNode node = candidate.getRootNode();
171 switch (node.getModificationType()) {
173 writer.writeByte(APPEARED);
174 writeChildren(writer, node.getChildNodes());
177 writer.writeByte(DELETE);
180 writer.writeByte(DISAPPEARED);
181 writeChildren(writer, node.getChildNodes());
183 case SUBTREE_MODIFIED:
184 writer.writeByte(SUBTREE_MODIFIED);
185 writeChildren(writer, node.getChildNodes());
188 writer.writeByte(UNMODIFIED);
191 writer.writeByte(WRITE);
192 writer.writeNormalizedNode(node.getDataAfter().get());
195 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());