Fix SubIdStatement/ObjectIdentifier ranges 93/92493/8
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 18 Sep 2020 22:12:07 +0000 (00:12 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 18 Sep 2020 23:22:14 +0000 (01:22 +0200)
RFC2578 makes it clear that each sub-identifier is an uint32 as
well as that there is at most 128 of them present in an ObjectIdentifier.

JIRA: YANGTOOLS-1134
Change-Id: Ic19baf8158c3e291c505c943bf16eae7cfd4ad58
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/rfc6643-model-api/src/main/java/org/opendaylight/yangtools/rfc6643/model/api/ObjectIdentifier.java
yang/rfc6643-model-api/src/main/java/org/opendaylight/yangtools/rfc6643/model/api/SubIdEffectiveStatement.java
yang/rfc6643-model-api/src/main/java/org/opendaylight/yangtools/rfc6643/model/api/SubIdSchemaNode.java
yang/rfc6643-model-api/src/main/java/org/opendaylight/yangtools/rfc6643/model/api/SubIdStatement.java
yang/rfc6643-parser-support/src/main/java/org/opendaylight/yangtools/rfc6643/parser/OidStatementSupport.java
yang/rfc6643-parser-support/src/main/java/org/opendaylight/yangtools/rfc6643/parser/SubIdEffectiveStatementImpl.java
yang/rfc6643-parser-support/src/main/java/org/opendaylight/yangtools/rfc6643/parser/SubIdStatementImpl.java
yang/rfc6643-parser-support/src/main/java/org/opendaylight/yangtools/rfc6643/parser/SubIdStatementSupport.java
yang/rfc6643-parser-support/src/test/java/org/opendaylight/yangtools/rfc6643/parser/IetfYangSmiv2ExtensionPluginTest.java

index c97a12379ca1bc8bc5124915175dadb46b8d427a..806b237a1ba3ce87685f476b33952c8f55a2eca1 100644 (file)
@@ -19,6 +19,7 @@ import java.util.stream.IntStream;
 import org.checkerframework.checker.regex.qual.Regex;
 import org.opendaylight.yangtools.concepts.Identifier;
 import org.opendaylight.yangtools.concepts.WritableObject;
+import org.opendaylight.yangtools.yang.common.Uint32;
 
 /**
  * An OID, or ObjectIdentifier, as defined by ITU and ISO/IEC.
@@ -32,20 +33,21 @@ public final class ObjectIdentifier implements Identifier, WritableObject {
     private static final Pattern CHECK_OID_PATTERN = Pattern.compile(CHECK_OID_REGEX);
     private static final Pattern SPLIT_PATTERN = Pattern.compile(".", Pattern.LITERAL);
 
-    private final int[] components;
+    private final int[] subIdentifiers;
 
-    private ObjectIdentifier(final int[] components) {
-        this.components = components;
+    private ObjectIdentifier(final int[] subIdentifiers) {
+        this.subIdentifiers = subIdentifiers;
     }
 
     /**
-     * Create an {@link ObjectIdentifier} from its integer components.
+     * Create an {@link ObjectIdentifier} from its integer components. Each sub-identifier is interpreted as an unsigned
+     * integer.
      *
-     * @param components OID items
+     * @param subIdentifiers OID sub-identifiers
      * @return An ObjectIdentifier.
      */
-    public static ObjectIdentifier forComponents(final int... components) {
-        return new ObjectIdentifier(components.clone());
+    public static ObjectIdentifier of(final int... subIdentifiers) {
+        return new ObjectIdentifier(subIdentifiers.clone());
     }
 
     /**
@@ -58,13 +60,13 @@ public final class ObjectIdentifier implements Identifier, WritableObject {
         return new ObjectIdentifier(parseObjectId(str));
     }
 
-    public int[] getComponents() {
+    public int[] getSubIdentifiers() {
         // Always make a defensive copy
-        return components.clone();
+        return subIdentifiers.clone();
     }
 
-    public IntStream streamComponents() {
-        return Arrays.stream(components);
+    public IntStream streamSubIdentifiers() {
+        return Arrays.stream(subIdentifiers);
     }
 
     /**
@@ -76,8 +78,8 @@ public final class ObjectIdentifier implements Identifier, WritableObject {
      * @throws IOException If an I/O error is reported
      */
     public static ObjectIdentifier readFrom(final DataInput in) throws IOException {
-        final int count = in.readInt();
-        checkArgument(count >= 0, "Illegal item count");
+        final int count = in.readUnsignedByte();
+        checkArgument(count >= 0 && count <= 128, "Illegal item count %s", count);
 
         final int[] oid = new int[count];
         for (int index = 0; index < count; ++index) {
@@ -89,29 +91,29 @@ public final class ObjectIdentifier implements Identifier, WritableObject {
 
     @Override
     public void writeTo(final DataOutput out) throws IOException {
-        out.writeInt(components.length);
-        for (int i : components) {
+        out.writeByte(subIdentifiers.length);
+        for (int i : subIdentifiers) {
             out.writeInt(i);
         }
     }
 
     @Override
     public int hashCode() {
-        return Arrays.hashCode(components);
+        return Arrays.hashCode(subIdentifiers);
     }
 
     @Override
     public boolean equals(final Object obj) {
         return this == obj || obj instanceof ObjectIdentifier
-                && Arrays.equals(components, ((ObjectIdentifier) obj).components);
+                && Arrays.equals(subIdentifiers, ((ObjectIdentifier) obj).subIdentifiers);
     }
 
     @Override
     public String toString() {
         StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append(components[0]);
-        for (int index = 1; index < components.length; index++) {
-            stringBuilder.append('.').append(components[index]);
+        stringBuilder.append(subIdentifiers[0]);
+        for (int index = 1; index < subIdentifiers.length; index++) {
+            stringBuilder.append('.').append(subIdentifiers[index]);
         }
         return stringBuilder.toString();
     }
@@ -120,9 +122,11 @@ public final class ObjectIdentifier implements Identifier, WritableObject {
         checkArgument(CHECK_OID_PATTERN.matcher(objectId).matches(), "Wrong format for OID: '%s'", objectId);
 
         final String[] splitOid = SPLIT_PATTERN.split(objectId);
+        checkArgument(splitOid.length <= 128, "Object Identifier can have at most 128 sub-identifiers");
+
         final int[] oid = new int[splitOid.length];
         for (int index = 0; index < splitOid.length; index ++) {
-            oid[index] = Integer.parseInt(splitOid[index]);
+            oid[index] = Uint32.valueOf(splitOid[index]).intValue();
         }
         return oid;
     }
index 0339d8b4563f11e18cc02673f0047c2e5fe4c29b..4f162b9f6070948dd7af53af1befa471bafd8158 100644 (file)
@@ -8,11 +8,12 @@
 package org.opendaylight.yangtools.rfc6643.model.api;
 
 import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 @Beta
-public interface SubIdEffectiveStatement extends EffectiveStatement<Integer, SubIdStatement> {
+public interface SubIdEffectiveStatement extends EffectiveStatement<Uint32, SubIdStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return IetfYangSmiv2ExtensionsMapping.SUB_ID;
index c696abef601d3694e6caf5f87153e63781bfee7f..3fdb5f648c5f83d287b89f28a901440258185414 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.yangtools.rfc6643.model.api;
 
 import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 
 @Beta
 public interface SubIdSchemaNode extends UnknownSchemaNode {
 
-    int getArgument();
+    @NonNull Uint32 getArgument();
 }
index ff0166e239155b25a4ec031da7c309c0697d3032..b422fb102d3a60b603aa9761c007324b29a697c9 100644 (file)
@@ -8,11 +8,12 @@
 package org.opendaylight.yangtools.rfc6643.model.api;
 
 import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 
 @Beta
-public interface SubIdStatement extends UnknownStatement<Integer> {
+public interface SubIdStatement extends UnknownStatement<Uint32> {
     @Override
     default StatementDefinition statementDefinition() {
         return IetfYangSmiv2ExtensionsMapping.SUB_ID;
index 1539109020a53cadf905eabd3099902b508e25d7..47bbb8021abc4c37f4f73c7a49bbf282c75d9abb 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 @Beta
 public final class OidStatementSupport
@@ -36,7 +37,11 @@ public final class OidStatementSupport
 
     @Override
     public ObjectIdentifier parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
-        return ObjectIdentifier.forString(value);
+        try {
+            return ObjectIdentifier.forString(value);
+        } catch (IllegalArgumentException e) {
+            throw new SourceException(ctx.getStatementSourceReference(), e, "Invalid object identifier '%s'", value);
+        }
     }
 
     @Override
index 427c365f30a2d80950f3865af930b31936b5b2b8..650293f299c5854674314ae267ba3aa7c6d8c963 100644 (file)
@@ -13,25 +13,26 @@ import org.opendaylight.yangtools.rfc6643.model.api.SubIdEffectiveStatement;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdSchemaNode;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdStatement;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.UnknownEffectiveStatementBase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-final class SubIdEffectiveStatementImpl extends UnknownEffectiveStatementBase<Integer, SubIdStatement>
+final class SubIdEffectiveStatementImpl extends UnknownEffectiveStatementBase<Uint32, SubIdStatement>
         implements SubIdEffectiveStatement, SubIdSchemaNode {
 
     private final SchemaPath path;
 
-    SubIdEffectiveStatementImpl(final StmtContext<Integer, SubIdStatement, ?> ctx,
+    SubIdEffectiveStatementImpl(final StmtContext<Uint32, SubIdStatement, ?> ctx,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
         super(ctx, substatements);
         path = ctx.getParentContext().getSchemaPath().get().createChild(getNodeType());
     }
 
     @Override
-    public int getArgument() {
-        return argument().intValue();
+    public Uint32 getArgument() {
+        return argument();
     }
 
     @Override
index 1a288c6a8c3c9c95bf38d9cdad2c8d821a46e4fa..508bc41ed8000ff9369e182373d7446c8da3b2f0 100644 (file)
@@ -9,11 +9,12 @@ package org.opendaylight.yangtools.rfc6643.parser;
 
 import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdStatement;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.ArgumentToString.WithSubstatements;
 
-final class SubIdStatementImpl extends WithSubstatements<Integer> implements SubIdStatement {
-    SubIdStatementImpl(final Integer argument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+final class SubIdStatementImpl extends WithSubstatements<Uint32> implements SubIdStatement {
+    SubIdStatementImpl(final Uint32 argument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
         super(argument, substatements);
     }
 }
index 0171f2981bd94c2fcbe162ae88f658467d7a7f0d..821f5beef294c74d715a76dd57c4be9559009114 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.rfc6643.model.api.IetfYangSmiv2ExtensionsMapping;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdEffectiveStatement;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdStatement;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
@@ -20,7 +21,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 
 @Beta
 public final class SubIdStatementSupport
-        extends BaseStatementSupport<Integer, SubIdStatement, SubIdEffectiveStatement> {
+        extends BaseStatementSupport<Uint32, SubIdStatement, SubIdEffectiveStatement> {
     private static final SubstatementValidator SUBSTATEMENT_VALIDATOR =
             SubstatementValidator.builder(IetfYangSmiv2ExtensionsMapping.SUB_ID).build();
     private static final SubIdStatementSupport INSTANCE = new SubIdStatementSupport();
@@ -34,8 +35,8 @@ public final class SubIdStatementSupport
     }
 
     @Override
-    public Integer parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
-        return Integer.parseUnsignedInt(value);
+    public Uint32 parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        return Uint32.valueOf(value);
     }
 
     @Override
@@ -44,26 +45,26 @@ public final class SubIdStatementSupport
     }
 
     @Override
-    protected SubIdStatement createDeclared(final StmtContext<Integer, SubIdStatement, ?> ctx,
+    protected SubIdStatement createDeclared(final StmtContext<Uint32, SubIdStatement, ?> ctx,
             final ImmutableList<? extends DeclaredStatement<?>> substatements) {
         return new SubIdStatementImpl(ctx.coerceStatementArgument(), substatements);
     }
 
     @Override
-    protected SubIdStatement createEmptyDeclared(final StmtContext<Integer, SubIdStatement, ?> ctx) {
+    protected SubIdStatement createEmptyDeclared(final StmtContext<Uint32, SubIdStatement, ?> ctx) {
         return createDeclared(ctx, ImmutableList.of());
     }
 
     @Override
     protected SubIdEffectiveStatement createEffective(
-            final StmtContext<Integer, SubIdStatement, SubIdEffectiveStatement> ctx,
+            final StmtContext<Uint32, SubIdStatement, SubIdEffectiveStatement> ctx,
             final SubIdStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
         return new SubIdEffectiveStatementImpl(ctx, substatements);
     }
 
     @Override
     protected SubIdEffectiveStatement createEmptyEffective(
-            final StmtContext<Integer, SubIdStatement, SubIdEffectiveStatement> ctx, final SubIdStatement declared) {
+            final StmtContext<Uint32, SubIdStatement, SubIdEffectiveStatement> ctx, final SubIdStatement declared) {
         return createEffective(ctx, declared, ImmutableList.of());
     }
 }
index 31e4456bc65dab68e4e71606b2bf93f6143cf909..c0d599a30885e4f56e54936b97f53ca69477e1af 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.yangtools.rfc6643.model.api.ObjectIdentifier;
 import org.opendaylight.yangtools.rfc6643.model.api.OidSchemaNode;
 import org.opendaylight.yangtools.rfc6643.model.api.SubIdSchemaNode;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
@@ -103,9 +104,9 @@ public class IetfYangSmiv2ExtensionPluginTest {
         assertTrue(testNumberLeaf.getUnknownSchemaNodes().size() == 3);
         testNumberLeaf.getUnknownSchemaNodes().forEach(unknownSchemaNode -> {
             if (unknownSchemaNode instanceof SubIdSchemaNode) {
-                assertEquals(((SubIdSchemaNode) unknownSchemaNode).getArgument(), 2);
+                assertEquals(Uint32.TWO, ((SubIdSchemaNode) unknownSchemaNode).getArgument());
             } else if (unknownSchemaNode instanceof DefValSchemaNode) {
-                assertEquals(((DefValSchemaNode) unknownSchemaNode).getArgument(), "0");
+                assertEquals("0", ((DefValSchemaNode) unknownSchemaNode).getArgument());
             }
         });
     }