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.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);
60 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
63 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in) 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);
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.written(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.written(reader.readNormalizedNode());
123 rootNode = AbstractDataTreeCandidateNode.createUnmodified();
126 throw new IllegalArgumentException("Unhandled node type " + type);
129 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
132 private static void writeChildren(final NormalizedNodeDataOutput out,
133 final Collection<DataTreeCandidateNode> children) throws IOException {
134 out.writeInt(children.size());
135 for (DataTreeCandidateNode child : children) {
136 writeNode(out, child);
140 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
142 switch (node.getModificationType()) {
144 out.writeByte(APPEARED);
145 out.writePathArgument(node.getIdentifier());
146 writeChildren(out, node.getChildNodes());
149 out.writeByte(DELETE);
150 out.writePathArgument(node.getIdentifier());
153 out.writeByte(DISAPPEARED);
154 out.writePathArgument(node.getIdentifier());
155 writeChildren(out, node.getChildNodes());
157 case SUBTREE_MODIFIED:
158 out.writeByte(SUBTREE_MODIFIED);
159 out.writePathArgument(node.getIdentifier());
160 writeChildren(out, node.getChildNodes());
163 out.writeByte(WRITE);
164 out.writeNormalizedNode(node.getDataAfter().get());
167 out.writeByte(UNMODIFIED);
170 throwUnhandledNodeType(node);
174 public static void writeDataTreeCandidate(final DataOutput out, final DataTreeCandidate candidate)
176 try (NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(out,
177 PayloadVersion.current().getStreamVersion())) {
178 writer.writeYangInstanceIdentifier(candidate.getRootPath());
180 final DataTreeCandidateNode node = candidate.getRootNode();
181 switch (node.getModificationType()) {
183 writer.writeByte(APPEARED);
184 writeChildren(writer, node.getChildNodes());
187 writer.writeByte(DELETE);
190 writer.writeByte(DISAPPEARED);
191 writeChildren(writer, node.getChildNodes());
193 case SUBTREE_MODIFIED:
194 writer.writeByte(SUBTREE_MODIFIED);
195 writeChildren(writer, node.getChildNodes());
198 writer.writeByte(UNMODIFIED);
201 writer.writeByte(WRITE);
202 writer.writeNormalizedNode(node.getDataAfter().get());
205 throwUnhandledNodeType(node);
210 private static void throwUnhandledNodeType(final DataTreeCandidateNode node) {
211 throw new IllegalArgumentException("Unhandled node type " + node.getModificationType());