Add (DOM)DataTreeIdentifier serialization proxies 71/109271/1
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 9 Dec 2023 13:18:03 +0000 (14:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 10 Dec 2023 10:43:00 +0000 (11:43 +0100)
Further evolution of these two classes will require allowing for two
distinct specializations.

In order to be able to do that, we need to disconnect them from their
serial form.

This patch instroduces serialization proxies, which know how to write
out and read in these objects without referencing their class name.

JIRA: MDSAL-845
Change-Id: I2b50d3aa5f752d6181dab991a5a8282b079b16df
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 9286037f2852d197c4384511fce97c551e2b8dc3)

binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DTIv1.java [new file with mode: 0644]
binding/mdsal-binding-api/src/test/java/org/opendaylight/mdsal/binding/api/DataTreeIdentifierTest.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DTIv1.java [new file with mode: 0644]
dom/mdsal-dom-api/src/test/java/org/opendaylight/mdsal/dom/api/DOMDataTreeIdentifierTest.java

diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DTIv1.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DTIv1.java
new file mode 100644 (file)
index 0000000..eae69b0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.binding.api;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * A serialization proxy for {@link DataTreeIdentifier}.
+ */
+final class DTIv1 implements Externalizable {
+    @java.io.Serial
+    private static final long serialVersionUID = 1L;
+
+    private DataTreeIdentifier<?> id;
+
+    @SuppressWarnings("redundantModifier")
+    public DTIv1() {
+        // For Externalizable
+    }
+
+    DTIv1(final DataTreeIdentifier<?> id) {
+        this.id = requireNonNull(id);
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        id.getDatastoreType().writeTo(out);
+        out.writeObject(id.getRootIdentifier());
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        id = DataTreeIdentifier.create(LogicalDatastoreType.readFrom(in), (InstanceIdentifier<?>) in.readObject());
+    }
+
+    @java.io.Serial
+    Object readResolve() {
+        return verifyNotNull(id);
+    }
+}
index 0b733c8f78d16e4da2cf3a147df98b8d97731c69..9abfaa4866300cbd6360d64d5ae80076cb0679f4 100644 (file)
@@ -12,6 +12,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import org.junit.jupiter.api.Test;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
@@ -58,6 +62,21 @@ class DataTreeIdentifierTest {
         assertNotEquals(TEST_IDENTIFIER1, new Object(), "Different object");
     }
 
+    @Test
+    void serializationTest() throws Exception {
+        final var bos = new ByteArrayOutputStream();
+        try (var oos = new ObjectOutputStream(bos)) {
+            oos.writeObject(TEST_IDENTIFIER1);
+        }
+
+        final var bytes = bos.toByteArray();
+        assertEquals(728, bytes.length);
+
+        try (var ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
+            assertEquals(TEST_IDENTIFIER1, ois.readObject());
+        }
+    }
+
     private interface TestDataObject1 extends ChildOf<DataRoot> {
         @Override
         default Class<? extends DataObject> implementedInterface() {
diff --git a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DTIv1.java b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DTIv1.java
new file mode 100644 (file)
index 0000000..71b978a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.api;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+/**
+ * A serialization proxy for {@link DOMDataTreeIdentifier}.
+ */
+final class DTIv1 implements Externalizable {
+    @java.io.Serial
+    private static final long serialVersionUID = 1L;
+
+    private DOMDataTreeIdentifier id;
+
+    @SuppressWarnings("redundantModifier")
+    public DTIv1() {
+        // For Externalizable
+    }
+
+    DTIv1(final DOMDataTreeIdentifier id) {
+        this.id = requireNonNull(id);
+    }
+
+    @Override
+    public void writeExternal(final ObjectOutput out) throws IOException {
+        id.getDatastoreType().writeTo(out);
+        out.writeObject(id.getRootIdentifier());
+    }
+
+    @Override
+    public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+        id = new DOMDataTreeIdentifier(LogicalDatastoreType.readFrom(in), (YangInstanceIdentifier) in.readObject());
+    }
+
+    @java.io.Serial
+    Object readResolve() {
+        return verifyNotNull(id);
+    }
+}
index eb5b20dade1cbe227b741c7a57959e6433b310e3..fecd65b040a71068f76f00059ce10005190ce738 100644 (file)
@@ -12,6 +12,10 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import org.junit.jupiter.api.Test;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -24,16 +28,16 @@ class DOMDataTreeIdentifierTest {
     private static final String TEST_LISTS = "test-lists";
     private static final String COMPARE_FIRST_LISTS = "A-test-lists";
     private static final String COMPARE_SECOND_LISTS = "B-test-lists";
-    private static final QNameModule TEST_MODULE = QNameModule.create(XMLNamespace.of(
-            "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:store"));
-    private static final YangInstanceIdentifier REF_YII_IID = YangInstanceIdentifier.of(
-            QName.create(TEST_MODULE, REF_LISTS));
-    private static final YangInstanceIdentifier TEST_YII_IID = YangInstanceIdentifier.of(
-            QName.create(TEST_MODULE, TEST_LISTS));
-    private static final DOMDataTreeIdentifier REF_TREE = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
-            REF_YII_IID);
-    private static final DOMDataTreeIdentifier
-        TEST_DIFF_TREE = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,TEST_YII_IID);
+    private static final QNameModule TEST_MODULE =
+        QNameModule.create(XMLNamespace.of("urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:store"));
+    private static final YangInstanceIdentifier REF_YII_IID =
+        YangInstanceIdentifier.of(QName.create(TEST_MODULE, REF_LISTS));
+    private static final YangInstanceIdentifier TEST_YII_IID =
+        YangInstanceIdentifier.of(QName.create(TEST_MODULE, TEST_LISTS));
+    private static final DOMDataTreeIdentifier REF_TREE =
+        new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, REF_YII_IID);
+    private static final DOMDataTreeIdentifier TEST_DIFF_TREE =
+        new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,TEST_YII_IID);
 
     @Test
     void constructTest() {
@@ -85,4 +89,19 @@ class DOMDataTreeIdentifierTest {
             + "root=/(urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:store)ref-lists}",
             REF_TREE.toString());
     }
+
+    @Test
+    void serializationTest() throws Exception {
+        final var bos = new ByteArrayOutputStream();
+        try (var oos = new ObjectOutputStream(bos)) {
+            oos.writeObject(REF_TREE);
+        }
+
+        final var bytes = bos.toByteArray();
+        assertEquals(561, bytes.length);
+
+        try (var ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
+            assertEquals(REF_TREE, ois.readObject());
+        }
+    }
 }