Redefine AbstractMessageParser object parsing 83/96983/5
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 21 Jul 2021 20:24:11 +0000 (22:24 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 26 Jul 2021 08:02:28 +0000 (10:02 +0200)
All AbstractMessageParser.validate() interact with the list of objects
by peeking at the first element and removing it when handled. While
the List contract supports it, there is no efficient implementation:
LinkedList is wasteful with memory (and its locality), ArrayList ends
up shifting arrays all the time.

Deal with this dilemma by recognizing we are dealing with a Queue, and
realize it through ArrayDeque. Let users deal with the logic rewrite,
which ends up being rather sensible: they are always looking only at the
first element anyway.

This also exposes a few places where we can run into runtime exceptions
-- mark those with FIXMEs for future improvement.

JIRA: BGPCEP-976
Change-Id: I882c7208dddd61f368499fd661e6d090752d144d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
19 files changed:
pcep/auto-bandwidth-extension/src/main/java/org/opendaylight/protocol/pcep/auto/bandwidth/extension/PcRptMessageCodec.java
pcep/auto-bandwidth-extension/src/test/java/org/opendaylight/protocol/pcep/auto/bandwidth/extension/PcRptMessageCodecTest.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPCloseMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPErrorMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPKeepAliveMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPMonitoringReplyMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPMonitoringRequestMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPNotificationMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPOpenMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPReplyMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPRequestMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/message/PCEPStartTLSMessageParser.java
pcep/base-parser/src/main/java/org/opendaylight/protocol/pcep/parser/util/Util.java
pcep/ietf-stateful/src/main/java/org/opendaylight/protocol/pcep/ietf/initiated/InitiatedPCInitiateMessageParser.java
pcep/ietf-stateful/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful/StatefulErrorMessageParser.java
pcep/ietf-stateful/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful/StatefulPCReportMessageParser.java
pcep/ietf-stateful/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful/StatefulPCUpdateRequestMessageParser.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/AbstractMessageParser.java
pcep/spi/src/test/java/org/opendaylight/protocol/pcep/spi/AbstractMessageParserTest.java

index 189d927235688daf3e5a1a3d01d2f6271c6790cb..12195eaac5f46bcbddff418967e2713ae8be9c9d 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 import io.netty.buffer.ByteBuf;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.ietf.stateful.StatefulPCReportMessageParser;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.auto.bandwidth.rev181109.Bandwidth1;
@@ -35,7 +36,7 @@ public class PcRptMessageCodec extends StatefulPCReportMessageParser {
     }
 
     @Override
-    protected Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+    protected Reports getValidReports(final Queue<Object> objects, final List<Message> errors) {
         final Optional<Object> find = Iterables.tryFind(objects, Predicates.instanceOf(BandwidthUsage.class));
         final Object object;
         if (find.isPresent()) {
index 6af4ef053c9b88e468cb7d32d7ba7a2c36ddc3cb..14e6f88a4d8f66d25a153f295595888d0795a34a 100644 (file)
@@ -11,12 +11,13 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Queue;
 import javax.xml.bind.DatatypeConverter;
 import org.junit.Before;
 import org.junit.Test;
@@ -79,8 +80,8 @@ public class PcRptMessageCodecTest {
         final Lsp lsp = new LspBuilder().setPlspId(new PlspId(Uint32.ONE))
                 .setTlvs(new TlvsBuilder().setLspIdentifiers(identifier).build()).build();
         final Ero ero = new EroBuilder().build();
-        final List<Object> objects = Lists.newArrayList(lsp, ero, bw);
-        final Reports validReports = codec.getValidReports(objects, Collections.emptyList());
+        final Queue<Object> objects = new ArrayDeque<>(List.of(lsp, ero, bw));
+        final Reports validReports = codec.getValidReports(objects, List.of());
         assertNotNull(validReports.getPath().getBandwidth().augmentation(Bandwidth1.class));
         assertTrue(objects.isEmpty());
     }
@@ -95,7 +96,7 @@ public class PcRptMessageCodecTest {
         builder.setIpv4TunnelEndpointAddress(new Ipv4AddressNoZone("127.0.1.3"));
         final Lsp lsp = new LspBuilder().setPlspId(new PlspId(Uint32.ONE)).build();
         final Ero ero = new EroBuilder().build();
-        final List<Object> objects = Lists.newArrayList(lsp, ero, bw);
+        final Queue<Object> objects = new ArrayDeque<>(List.of(lsp, ero, bw));
         final Reports validReports = codec.getValidReports(objects, new ArrayList<>());
         assertNull(validReports);
     }
index 118799990db715989d3369ba18ebbc471e909677..c0559ec264672165f90f9a4c89969abf48901f4e 100644 (file)
@@ -7,10 +7,12 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -37,24 +39,23 @@ public class PCEPCloseMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf out) {
-        Preconditions.checkArgument(message instanceof CloseMessage,
+        checkArgument(message instanceof CloseMessage,
                 "Wrong instance of Message. Passed instance of %s. Need CloseMessage.", message.getClass());
         final CCloseMessage close = ((CloseMessage) message).getCCloseMessage();
-        Preconditions.checkArgument(close.getCClose() != null, "Close Object must be present in Close Message.");
+        checkArgument(close.getCClose() != null, "Close Object must be present in Close Message.");
         final ByteBuf buffer = Unpooled.buffer();
         serializeObject(close.getCClose(), buffer);
         MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
     @Override
-    protected Close validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
-        if (objects.isEmpty() || !(objects.get(0) instanceof CClose)) {
+    protected Close validate(final Queue<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+        checkArgument(objects != null, "Passed list can't be null.");
+        final Object o = objects.poll();
+        if (!(o instanceof CClose)) {
             throw new PCEPDeserializerException("Close message doesn't contain CLOSE object.");
         }
-        final Object o = objects.get(0);
         final CCloseMessage msg = new CCloseMessageBuilder().setCClose((CClose) o).build();
-        objects.remove(0);
         if (!objects.isEmpty()) {
             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
         }
index 136acb7b3ba41cbe4f6964fda5604b2598a5de20..b282c7effe807334d0f119af03baaf6f2a765861 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -83,47 +86,49 @@ public class PCEPErrorMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    protected PcerrMessage validate(final List<Object> objects, final List<Message> errors)
+    protected PcerrMessage validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
-        if (objects.isEmpty()) {
-            throw new PCEPDeserializerException("Error message is empty.");
-        }
+        checkArgument(objects != null, "Passed list can't be null.");
+
         final List<Rps> requestParameters = new ArrayList<>();
         final List<Errors> errorObjects = new ArrayList<>();
-        final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
-
-        Object obj = objects.get(0);
-        State state = State.INIT;
 
-        if (obj instanceof ErrorObject) {
-            final ErrorObject o = (ErrorObject) obj;
-            errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
-            state = State.ERROR_IN;
-        } else if (obj instanceof Rp) {
-            final Rp o = (Rp) obj;
-            if (o.getProcessingRule()) {
+        final State initialState;
+        final Object first = objects.poll();
+        if (first instanceof ErrorObject) {
+            errorObjects.add(new ErrorsBuilder().setErrorObject((ErrorObject) first).build());
+            initialState = State.ERROR_IN;
+        } else if (first instanceof Rp) {
+            final Rp rp = (Rp) first;
+            if (rp.getProcessingRule()) {
                 errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.empty()));
                 return null;
             }
-            requestParameters.add(new RpsBuilder().setRp(o).build());
-            state = State.RP_IN;
-        }
-        if (state.equals(State.INIT)) {
+            requestParameters.add(new RpsBuilder().setRp(rp).build());
+            initialState = State.RP_IN;
+        } else if (first == null) {
+            throw new PCEPDeserializerException("Error message is empty.");
+        } else {
             throw new PCEPDeserializerException("At least one PCEPErrorObject is mandatory.");
         }
-        objects.remove(0);
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+
+        final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
+        State state = initialState;
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             if (obj instanceof UnknownObject) {
                 return new PcerrBuilder()
-                        .setPcerrMessage(msgBuilder.setErrors(((UnknownObject) obj).getErrors()).build()).build();
+                        .setPcerrMessage(msgBuilder.setErrors(((UnknownObject) obj).getErrors()).build())
+                        .build();
             }
+
             state = insertObject(state, errorObjects, obj, requestParameters, msgBuilder);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         if (errorObjects.isEmpty()) {
             throw new PCEPDeserializerException("At least one PCEPErrorObject is mandatory.");
         }
index beaa5453308750e96aa32af9fbf338fb2a42d799..da1a64814317fcdb66e7f1f91f6b0e164828f40c 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -41,7 +42,7 @@ public class PCEPKeepAliveMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    protected KeepaliveMessage validate(final List<Object> objects, final List<Message> errors)
+    protected KeepaliveMessage validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         if (objects != null && !objects.isEmpty()) {
             throw new PCEPDeserializerException("Keepalive message should not contain any objects.");
index e1f69d72ba26a1b1ca08cb89a451200abd8e5a60..9be69652b0d652794b93488bf77f5bf7ca569a15 100644 (file)
@@ -5,15 +5,16 @@
  * 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.protocol.pcep.parser.message;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.parser.util.Util;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
@@ -52,10 +53,10 @@ public class PCEPMonitoringReplyMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf buffer) {
-        Preconditions.checkArgument(message instanceof Pcmonrep,
+        checkArgument(message instanceof Pcmonrep,
                 "Wrong instance of Message. Passed instance of %s. Need Pcmonrep.", message.getClass());
         final PcmonrepMessage monRepMsg = ((Pcmonrep) message).getPcmonrepMessage();
-        Preconditions.checkArgument(monRepMsg.getMonitoring() != null, "MONITORING object is mandatory.");
+        checkArgument(monRepMsg.getMonitoring() != null, "MONITORING object is mandatory.");
         final ByteBuf body = Unpooled.buffer();
         serializeObject(monRepMsg.getMonitoring(), body);
         serializeObject(monRepMsg.getPccIdReq(), body);
@@ -78,29 +79,34 @@ public class PCEPMonitoringReplyMessageParser extends AbstractMessageParser {
     }
 
     private void serializeMetricPce(final MetricPce metricPce, final ByteBuf buffer) {
-        Preconditions.checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
+        checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
         serializeObject(metricPce.getPceId(), buffer);
         serializeObject(metricPce.getProcTime(), buffer);
         serializeObject(metricPce.getOverload(), buffer);
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors)
+    protected Message validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
-        if (objects.isEmpty()) {
+        checkArgument(objects != null, "Passed list can't be null.");
+
+        final Object monitoring = objects.poll();
+        if (monitoring == null) {
             throw new PCEPDeserializerException("Pcmonrep message cannot be empty.");
         }
-        if (!(objects.get(0) instanceof Monitoring)) {
+        if (!(monitoring instanceof Monitoring)) {
             errors.add(createErrorMsg(PCEPErrors.MONITORING_OBJECT_MISSING, Optional.empty()));
             return null;
         }
-        final PcmonrepMessageBuilder builder = new PcmonrepMessageBuilder().setMonitoring((Monitoring) objects.get(0));
-        objects.remove(0);
-        if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
-            builder.setPccIdReq((PccIdReq) objects.get(0));
-            objects.remove(0);
+
+        final PcmonrepMessageBuilder builder = new PcmonrepMessageBuilder().setMonitoring((Monitoring) monitoring);
+
+        final Object obj = objects.peek();
+        if (obj instanceof PccIdReq) {
+            builder.setPccIdReq((PccIdReq)obj);
+            objects.remove();
         }
+
         validateSpecificMetrics(objects, builder);
         if (!objects.isEmpty()) {
             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
@@ -108,26 +114,29 @@ public class PCEPMonitoringReplyMessageParser extends AbstractMessageParser {
         return new PcmonrepBuilder().setPcmonrepMessage(builder.build()).build();
     }
 
-    private static void validateSpecificMetrics(final List<Object> objects, final PcmonrepMessageBuilder builder)
+    private static void validateSpecificMetrics(final Queue<Object> objects, final PcmonrepMessageBuilder builder)
             throws PCEPDeserializerException {
         final List<SpecificMetrics> specificMetrics = new ArrayList<>();
-        while (!objects.isEmpty()) {
+
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             final SpecificMetricsBuilder smb = new SpecificMetricsBuilder();
-            final List<MetricPce> metricPceList = new ArrayList<>();
-            if (objects.get(0) instanceof Rp) {
-                smb.setRp((Rp) objects.get(0));
-                objects.remove(0);
+            if (obj instanceof Rp) {
+                smb.setRp((Rp) obj);
+                objects.remove();
             }
-            while (!objects.isEmpty() && !(objects.get(0) instanceof Rp)) {
+
+            final List<MetricPce> metricPceList = new ArrayList<>();
+            for (obj = objects.peek(); obj != null && !(obj instanceof Rp); obj = objects.peek()) {
                 metricPceList.add(Util.validateMonitoringMetrics(objects));
             }
+
             if (smb.getRp() != null) {
-                smb.setMetricPce(metricPceList);
-                specificMetrics.add(smb.build());
+                specificMetrics.add(smb.setMetricPce(metricPceList).build());
             } else if (!metricPceList.isEmpty()) {
                 builder.setMonitoringMetricsList(new GeneralMetricsListBuilder().setMetricPce(metricPceList).build());
             }
         }
+
         if (!specificMetrics.isEmpty()) {
             builder.setMonitoringMetricsList(
                     new SpecificMetricsListBuilder().setSpecificMetrics(specificMetrics).build());
index dc9a86e65152270bb4eed1a911c67869969fda88..9f6cad16d342d758344fd7121d8cb3f214ccae9d 100644 (file)
@@ -13,6 +13,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
@@ -57,7 +58,7 @@ public class PCEPMonitoringRequestMessageParser extends PCEPRequestMessageParser
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors)
+    protected Message validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         Preconditions.checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
index 3c9e4621d359433abf97ba66ad2251f53e666f37..eb0fe026a6b3807ac591ca2538664e0ce1d45802 100644 (file)
@@ -7,12 +7,14 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -43,29 +45,25 @@ public class PCEPNotificationMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf out) {
-        Preconditions.checkArgument(message instanceof PcntfMessage,
+        checkArgument(message instanceof PcntfMessage,
                 "Wrong instance of Message. Passed instance of %s. Need PcntfMessage.", message.getClass());
         final ByteBuf buffer = Unpooled.buffer();
-        for (final Notifications n : ((PcntfMessage) message).getPcntfMessage().getNotifications()) {
-            if (n.getRps() != null) {
-                for (final Rps rps : n.getRps()) {
-                    serializeObject(rps.getRp(), buffer);
-                }
-            }
-            Preconditions.checkArgument(n.getNotifications() != null && !n.getNotifications().isEmpty(),
-                    "Message must contain at least one notification object");
-            for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcntf
-                    .message.pcntf.message.notifications.Notifications not : n.getNotifications()) {
-                serializeObject(not.getCNotification(), buffer);
+        for (final Notifications n : ((PcntfMessage) message).getPcntfMessage().nonnullNotifications()) {
+            for (final Rps rps : n.nonnullRps()) {
+                serializeObject(rps.getRp(), buffer);
             }
+
+            final var notifs = n.nonnullNotifications();
+            checkArgument(!notifs.isEmpty(), "Message must contain at least one notification object");
+            notifs.forEach(not -> serializeObject(not.getCNotification(), buffer));
         }
         MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors)
+    protected Message validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
+        checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
             throw new PCEPDeserializerException("Notification message cannot be empty.");
         }
@@ -86,24 +84,26 @@ public class PCEPNotificationMessageParser extends AbstractMessageParser {
             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
         }
         return new PcntfBuilder()
-                .setPcntfMessage(new PcntfMessageBuilder().setNotifications(compositeNotifications).build()).build();
+                .setPcntfMessage(new PcntfMessageBuilder().setNotifications(compositeNotifications).build())
+                .build();
     }
 
-    private static Notifications getValidNotificationComposite(final List<Object> objects, final List<Message> errors) {
+    private static Notifications getValidNotificationComposite(final Queue<Object> objects,
+            final List<Message> errors) {
         final List<Rps> requestParameters = new ArrayList<>();
         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcntf
             .message.pcntf.message.notifications.Notifications> notifications = new ArrayList<>();
-        Object obj;
 
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             if ((state = insertObject(state, obj, errors, requestParameters, notifications)) == null) {
                 return null;
             }
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
 
         if (notifications.isEmpty()) {
index ea7ebcae04e6701f39b12b91e41d25014a342230..58eda092a6e10ea972e1c36271f2e4998bde11ff 100644 (file)
@@ -7,10 +7,12 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -35,11 +37,11 @@ public class PCEPOpenMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf out) {
-        Preconditions.checkArgument(message instanceof OpenMessage,
+        checkArgument(message instanceof OpenMessage,
                 "Wrong instance of Message. Passed instance of %s. Need OpenMessage.", message.getClass());
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.message
             .OpenMessage open = ((OpenMessage) message).getOpenMessage();
-        Preconditions.checkArgument(open.getOpen() != null, "Open Object must be present in Open Message.");
+        checkArgument(open.getOpen() != null, "Open Object must be present in Open Message.");
         final ByteBuf buffer = Unpooled.buffer();
         serializeObject(open.getOpen(), buffer);
         MessageUtil.formatMessage(TYPE, buffer, out);
@@ -47,22 +49,17 @@ public class PCEPOpenMessageParser extends AbstractMessageParser {
 
     @Override
     protected org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Open validate(
-            final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
+            final Queue<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+        checkArgument(objects != null, "Passed list can't be null.");
 
-        if (objects.isEmpty() || !(objects.get(0) instanceof Open)) {
+        final Object open = objects.poll();
+        if (!(open instanceof Open)) {
             throw new PCEPDeserializerException("Open message doesn't contain OPEN object.");
         }
-
-        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.message
-            .OpenMessage msg = new OpenMessageBuilder().setOpen((Open) objects.get(0)).build();
-
-        objects.remove(0);
-
         if (!objects.isEmpty()) {
             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
         }
 
-        return new OpenBuilder().setOpenMessage(msg).build();
+        return new OpenBuilder().setOpenMessage(new OpenMessageBuilder().setOpen((Open) open).build()).build();
     }
 }
index e83b792618f167de8f4a703e409822476015703e..ca0751d2b5e2310a1c0c1629a3fa2ea724a2682e 100644 (file)
@@ -7,12 +7,14 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.parser.util.Util;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
@@ -64,14 +66,15 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf out) {
-        Preconditions.checkArgument(message instanceof Pcrep,
+        checkArgument(message instanceof Pcrep,
                 "Wrong instance of Message. Passed instance of %s. Need Pcrep.", message.getClass());
         final PcrepMessage repMsg = ((Pcrep) message).getPcrepMessage();
-        Preconditions.checkArgument(repMsg.getReplies() != null && !repMsg.getReplies().isEmpty(),
-                "Replies cannot be null or empty.");
+        final List<Replies> replies = repMsg.nonnullReplies();
+
+        checkArgument(!replies.isEmpty(), "Replies cannot be null or empty.");
         final ByteBuf buffer = Unpooled.buffer();
-        for (final Replies reply : repMsg.getReplies()) {
-            Preconditions.checkArgument(reply.getRp() != null, "Reply must contain RP object.");
+        for (final Replies reply : replies) {
+            checkArgument(reply.getRp() != null, "Reply must contain RP object.");
             serializeReply(reply, buffer);
         }
         MessageUtil.formatMessage(TYPE, buffer, out);
@@ -136,15 +139,15 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
     }
 
     protected void serializeMetricPce(final MetricPce metricPce, final ByteBuf buffer) {
-        Preconditions.checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
+        checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
         serializeObject(metricPce.getPceId(), buffer);
         serializeObject(metricPce.getProcTime(), buffer);
         serializeObject(metricPce.getOverload(), buffer);
     }
 
     @Override
-    protected Pcrep validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
-        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
+    protected Pcrep validate(final Queue<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+        checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
             throw new PCEPDeserializerException("Pcrep message cannot be empty.");
         }
@@ -161,63 +164,74 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
         return new PcrepBuilder().setPcrepMessage(new PcrepMessageBuilder().setReplies(replies).build()).build();
     }
 
-    protected Replies getValidReply(final List<Object> objects, final List<Message> errors)
+    protected Replies getValidReply(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
-        Object object = objects.remove(0);
-        if (!(object instanceof Rp)) {
+        Object obj = objects.remove();
+        if (!(obj instanceof Rp)) {
             errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
             return null;
         }
-        final Rp rp = (Rp) object;
-        final RepliesBuilder repliesBuilder = new RepliesBuilder();
-        if (!objects.isEmpty() && objects.get(0) instanceof Monitoring) {
-            repliesBuilder.setMonitoring((Monitoring) objects.get(0));
-            objects.remove(0);
+
+        final RepliesBuilder repliesBuilder = new RepliesBuilder().setRp((Rp) obj);
+        obj = objects.peek();
+        if (obj instanceof Monitoring) {
+            repliesBuilder.setMonitoring((Monitoring) obj);
+            objects.remove();
+            obj = objects.peek();
         }
-        if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
-            repliesBuilder.setPccIdReq((PccIdReq) objects.get(0));
-            objects.remove(0);
+        if (obj instanceof PccIdReq) {
+            repliesBuilder.setPccIdReq((PccIdReq) obj);
+            objects.remove();
+            // last option, no need to peek
         }
+
+        // note: this may modify 'objects'
         final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
-        Result res = null;
-        if (!objects.isEmpty()) {
-            if (objects.get(0) instanceof NoPath) {
-                res = handleNoPath((NoPath) objects.get(0), objects);
-            } else if (objects.get(0) instanceof Ero) {
-                res = handleEros(objects);
-            }
+        if (!vendorInfo.isEmpty()) {
+            repliesBuilder.setVendorInformationObject(vendorInfo);
         }
-        final List<MetricPce> metricPceList = new ArrayList<>();
-        if (!objects.isEmpty() && objects.get(0) instanceof PceId) {
+
+        final Result res;
+        obj = objects.peek();
+        if (obj instanceof NoPath) {
+            objects.remove();
+            res = handleNoPath((NoPath) obj, objects);
+        } else if (obj instanceof Ero) {
+            res = handleEros(objects);
+        } else {
+            res = null;
+        }
+
+        if (objects.peek() instanceof PceId) {
+            final List<MetricPce> metricPceList = new ArrayList<>();
             while (!objects.isEmpty()) {
                 metricPceList.add(Util.validateMonitoringMetrics(objects));
             }
+            if (!metricPceList.isEmpty()) {
+                repliesBuilder.setMetricPce(metricPceList);
+            }
         }
-        if (!vendorInfo.isEmpty()) {
-            repliesBuilder.setVendorInformationObject(vendorInfo);
-        }
-        if (!metricPceList.isEmpty()) {
-            repliesBuilder.setMetricPce(metricPceList);
-        }
-        return repliesBuilder.setRp(rp).setResult(res).build();
+
+        return repliesBuilder.setResult(res).build();
     }
 
-    private Result handleNoPath(final NoPath noPath, final List<Object> objects) {
-        objects.remove(0);
+    private Result handleNoPath(final NoPath noPath, final Queue<Object> objects) {
         final FailureCaseBuilder builder = new FailureCaseBuilder().setNoPath(noPath);
-        while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
+        for (Object obj = objects.peek(); obj != null && !(obj instanceof PceId); obj = objects.peek()) {
             this.parseAttributes(builder, objects);
         }
         return builder.build();
     }
 
-    private Result handleEros(final List<Object> objects) {
+    private Result handleEros(final Queue<Object> objects) {
         final SuccessBuilder builder = new SuccessBuilder();
         final List<Paths> paths = new ArrayList<>();
-        while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
+
+        for (Object obj = objects.peek(); obj != null && !(obj instanceof PceId); obj = objects.peek()) {
             final PathsBuilder pBuilder = new PathsBuilder();
-            if (objects.get(0) instanceof Ero) {
-                pBuilder.setEro((Ero ) objects.remove(0));
+            if (obj instanceof Ero) {
+                pBuilder.setEro((Ero) obj);
+                objects.remove();
             }
             final List<VendorInformationObject> vendorInfoObjects = addVendorInformationObjects(objects);
             if (!vendorInfoObjects.isEmpty()) {
@@ -230,17 +244,17 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
         return new SuccessCaseBuilder().setSuccess(builder.build()).build();
     }
 
-    protected void parseAttributes(final FailureCaseBuilder builder, final List<Object> objects) {
+    protected void parseAttributes(final FailureCaseBuilder builder, final Queue<Object> objects) {
         final List<Metrics> pathMetrics = new ArrayList<>();
 
-        Object obj;
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertObject(state, obj, builder, pathMetrics);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
         if (!pathMetrics.isEmpty()) {
             builder.setMetrics(pathMetrics);
@@ -323,18 +337,19 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
         }
     }
 
-    protected void parsePath(final PathsBuilder builder, final List<Object> objects) {
+    protected void parsePath(final PathsBuilder builder, final Queue<Object> objects) {
         final List<Metrics> pathMetrics = new ArrayList<>();
 
-        Object obj;
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertObject(state, obj, builder, pathMetrics);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         if (!pathMetrics.isEmpty()) {
             builder.setMetrics(pathMetrics);
         }
index 64b051fdd4d35d623801d8f31e44799427491f4e..1dbbc65b7030e42b4a8a2aee37adc49a503f7007 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.protocol.pcep.parser.message;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -95,11 +98,10 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
 
     @Override
     public void serializeMessage(final Message message, final ByteBuf out) {
-        Preconditions.checkArgument(message instanceof Pcreq,
+        checkArgument(message instanceof Pcreq,
                 "Wrong instance of Message. Passed instance of %s. Need Pcreq.", message.getClass());
         final PcreqMessage msg = ((Pcreq) message).getPcreqMessage();
-        Preconditions.checkArgument(msg.getRequests() != null && !msg.getRequests().isEmpty(),
-                "Requests cannot be null or empty.");
+        checkArgument(!msg.nonnullRequests().isEmpty(), "Requests cannot be null or empty.");
         final ByteBuf buffer = Unpooled.buffer();
         if (msg.getMonitoringRequest() != null) {
             serializeMonitoringRequest(msg.getMonitoringRequest(), buffer);
@@ -112,7 +114,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
     }
 
     protected void serializeRequest(final PcreqMessage msg, final ByteBuf buffer) {
-        for (final Requests req : msg.getRequests()) {
+        for (final Requests req : msg.nonnullRequests()) {
             serializeObject(req.getRp(), buffer);
             serializeVendorInformationObjects(req.getVendorInformationObject(), buffer);
             if (req.getPathKeyExpansion() != null) {
@@ -176,7 +178,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         }
         endpointRroPairList.forEach(pair -> {
             serializeObject(pair.getEndpointsObj(), buffer);
-            pair.getRros().forEach(rro -> {
+            pair.nonnullRros().forEach(rro -> {
                 if (rro.getRouteObject() instanceof ReportedRouteObjectCase) {
                     serializeObject(((ReportedRouteObjectCase) rro.getRouteObject()).getRro(), buffer);
                 } else if (rro.getRouteObject() instanceof SecondaryReportedRouteObjectCase) {
@@ -214,7 +216,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors)
+    protected Message validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         Preconditions.checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
@@ -237,7 +239,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         return new PcreqBuilder().setPcreqMessage(mBuilder.build()).build();
     }
 
-    protected List<Svec> getSvecs(final List<Object> objects) {
+    protected List<Svec> getSvecs(final Queue<Object> objects) {
         final List<Svec> svecList = new ArrayList<>();
         while (!objects.isEmpty()) {
             final SvecBuilder sBuilder = new SvecBuilder();
@@ -250,43 +252,53 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         return svecList;
     }
 
-    protected List<Requests> getRequests(final List<Object> objects, final List<Message> errors) {
+    protected List<Requests> getRequests(final Queue<Object> objects, final List<Message> errors) {
         final List<Requests> requests = new ArrayList<>();
-        while (!objects.isEmpty()) {
-            final RequestsBuilder rBuilder = new RequestsBuilder();
-            Rp rpObj = null;
-            if (!(objects.get(0) instanceof Rp)) {
+
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
+            if (!(obj instanceof Rp)) {
                 // if RP obj is missing return error only
                 errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
                 return null;
             }
-            rpObj = (Rp) objects.get(0);
-            objects.remove(0);
-            if (!rpObj.getProcessingRule()) {
-                errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.empty()));
-            } else {
+
+            final RequestsBuilder rBuilder = new RequestsBuilder();
+            final Rp rpObj = (Rp) obj;
+            objects.remove();
+
+            if (rpObj.getProcessingRule()) {
                 rBuilder.setRp(rpObj);
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.empty()));
             }
+
             final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
             if (!vendorInfo.isEmpty()) {
                 rBuilder.setVendorInformationObject(vendorInfo);
             }
+
             // expansion
-            if (rpObj.getPathKey() && objects.get(0) instanceof PathKey) {
-                rBuilder.setPathKeyExpansion(
-                        new PathKeyExpansionBuilder().setPathKey((PathKey) objects.get(0)).build());
+            if (rpObj.getPathKey()) {
+                // FIXME: this can fail on malformed messages (i.e. objects.isEmpty()), add an explicit check/error
+                obj = objects.element();
+                if (obj instanceof PathKey) {
+                    // FIXME: shouldn't we be also removing the object?
+                    rBuilder.setPathKeyExpansion(new PathKeyExpansionBuilder().setPathKey((PathKey) obj).build());
+                }
             }
 
-            if (objects.isEmpty() || !(objects.get(0) instanceof EndpointsObj)) {
+            obj = objects.peek();
+            if (!(obj instanceof EndpointsObj)) {
                 errors.add(createErrorMsg(PCEPErrors.END_POINTS_MISSING, Optional.of(rpObj)));
                 return null;
             }
 
             if (!rpObj.getP2mp()) {
                 // p2p
+                // FIXME: explicit check for empty/type?
+                final EndpointsObj ep = (EndpointsObj) objects.remove();
+
                 final P2pBuilder p2pBuilder = new P2pBuilder();
-                final EndpointsObj ep = (EndpointsObj) objects.get(0);
-                objects.remove(0);
                 if (!ep.getProcessingRule()) {
                     errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.of(rpObj)));
                 } else {
@@ -310,7 +322,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
     }
 
     protected SegmentComputation getP2PSegmentComputation(final P2pBuilder builder,
-                                                          final List<Object> objects,
+                                                          final Queue<Object> objects,
                                                           final List<Message> errors,
                                                           final Rp rp) {
         final List<Metrics> metrics = new ArrayList<>();
@@ -320,7 +332,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         while (!objects.isEmpty() && p2PState != P2PState.END) {
             p2PState = insertP2PObject(p2PState, objects, viObjects, builder, metrics, errors, rp);
             if (!p2PState.equals(P2PState.END)) {
-                objects.remove(0);
+                objects.remove();
             }
         }
         if (!metrics.isEmpty()) {
@@ -341,20 +353,23 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         return new SegmentComputationBuilder().setP2p(builder.build()).build();
     }
 
+    // Note: objects is expected to be non-empty and caller will remove the first object if non-empty
     private static P2PState insertP2PObject(final P2PState p2PState,
-                                            final List<Object> objects,
+                                            final Queue<Object> objects,
                                             final List<VendorInformationObject> viObjects,
                                             final P2pBuilder builder,
                                             final List<Metrics> metrics,
                                             final List<Message> errors,
                                             final Rp rp) {
-        final Object obj = objects.get(0);
+        final Object obj = objects.element();
         switch (p2PState) {
             case INIT:
                 if (obj instanceof Rro) {
                     builder.setRro((Rro) obj);
-                    objects.remove(0);
-                    final Object nextObj = objects.get(0);
+                    objects.remove();
+
+                    // FIXME: should we guard against empty objects?
+                    final Object nextObj = objects.element();
                     if (nextObj instanceof ReoptimizationBandwidth) {
                         builder.setReoptimizationBandwidth((ReoptimizationBandwidth) nextObj);
                     }
@@ -490,7 +505,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         END
     }
 
-    protected SegmentComputation getP2MPSegmentComputation(final List<Object> objects, final List<Message> errors,
+    protected SegmentComputation getP2MPSegmentComputation(final Queue<Object> objects, final List<Message> errors,
             final Rp rp) {
         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message
             .pcreq.message.requests.segment.computation.p2mp.Metric> metrics = new ArrayList<>();
@@ -501,7 +516,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         while (!objects.isEmpty() && state != P2MPState.END) {
             state = insertP2MPObject(state, objects, builder, epRros, metrics, errors, rp);
             if (!state.equals(P2MPState.END)) {
-                objects.remove(0);
+                objects.remove();
             }
         }
         if (!epRros.isEmpty()) {
@@ -522,7 +537,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
 
     private static boolean isValidReoptimizationRro(final List<EndpointRroPair> epRros) {
         for (EndpointRroPair epRro : epRros) {
-            if (epRro.getRros() == null || epRro.getRros().isEmpty()) {
+            if (epRro.nonnullRros().isEmpty()) {
                 return false;
             }
         }
@@ -538,12 +553,12 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         return true;
     }
 
-    private static P2MPState insertP2MPObject(final P2MPState p2MPState, final List<Object> objects,
+    private static P2MPState insertP2MPObject(final P2MPState p2MPState, final Queue<Object> objects,
             final P2mpBuilder builder, final List<EndpointRroPair> epRros,
             final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq
                 .message.pcreq.message.requests.segment.computation.p2mp.Metric> metrics,
             final List<Message> errors, final Rp rp) {
-        final Object obj = objects.get(0);
+        final Object obj = objects.element();
         switch (p2MPState) {
             case RP:
                 if (obj instanceof EndpointsObj) {
@@ -652,30 +667,32 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         RP, ENDPOINT, RRO_SRRO, BANDWIDTH, OF_IN, LSPA_IN, BANDWIDTH_IN, METRIC_IN, IRO_BNC_IN, LOAD_BIN, END
     }
 
-    private static Svec getValidSvec(final SvecBuilder builder, final List<Object> objects) {
-        Preconditions.checkArgument(objects != null && !objects.isEmpty(), "Passed list can't be null or empty.");
-
-        if (objects.get(0) instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types
-                .rev181109.svec.object.Svec) {
-            builder.setSvec((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109
-                                .svec.object.Svec) objects.get(0));
-            objects.remove(0);
+    // Note: objects is expected to be non-empty
+    private static Svec getValidSvec(final SvecBuilder builder, final Queue<Object> objects) {
+        final Object svec = objects.element();
+        if (svec instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.svec
+                .object.Svec) {
+            builder.setSvec((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.svec
+                .object.Svec) svec);
+            objects.remove();
         } else {
             return null;
         }
 
+        // FIXME: this list is not retained anywhere
         final List<Metrics> metrics = new ArrayList<>();
         final List<VendorInformationObject> viObjects = new ArrayList<>();
 
-        Object obj = null;
         SvecState state = SvecState.INIT;
-        while (!objects.isEmpty() && !state.equals(SvecState.END)) {
-            obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertP2PObject(state, obj, builder, metrics, viObjects);
-            if (!state.equals(SvecState.END)) {
-                objects.remove(0);
+            if (state == SvecState.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         if (!viObjects.isEmpty()) {
             builder.setVendorInformationObject(viObjects);
         }
@@ -686,23 +703,31 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         INIT, OF_IN, GC_IN, XRO_IN, METRIC_IN, VENDOR_INFO, END
     }
 
-    protected MonitoringRequest getMonitoring(final List<Object> objects) {
+    protected MonitoringRequest getMonitoring(final Queue<Object> objects) {
         final MonitoringRequestBuilder builder = new MonitoringRequestBuilder();
-        if (!objects.isEmpty() && objects.get(0) instanceof Monitoring) {
-            builder.setMonitoring((Monitoring) objects.get(0));
-            objects.remove(0);
+
+        Object obj = objects.peek();
+        if (obj instanceof Monitoring) {
+            builder.setMonitoring((Monitoring) obj);
+            objects.remove();
         } else {
             return null;
         }
-        if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
-            builder.setPccIdReq((PccIdReq) objects.get(0));
-            objects.remove(0);
+
+        obj = objects.peek();
+        if (obj instanceof PccIdReq) {
+            builder.setPccIdReq((PccIdReq) obj);
+            objects.remove();
+            obj = objects.peek();
         }
+
         final List<PceIdList> pceIdList = new ArrayList<>();
-        while (!objects.isEmpty() && objects.get(0) instanceof PceId) {
-            pceIdList.add(new PceIdListBuilder().setPceId((PceId) objects.get(0)).build());
-            objects.remove(0);
+        while (obj instanceof PceId) {
+            pceIdList.add(new PceIdListBuilder().setPceId((PceId) obj).build());
+            objects.remove();
+            obj = objects.peek();
         }
+
         if (!pceIdList.isEmpty()) {
             builder.setPceIdList(pceIdList);
         }
index a7e4dad5c601e82c4f57a69dacf5f2604a97af31..bca93cf46cd4cab8dc79deed723c4befef4c02bd 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -38,7 +39,7 @@ public class PCEPStartTLSMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    protected StartTlsMessage validate(final List<Object> objects, final List<Message> errors)
+    protected StartTlsMessage validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         if (objects != null && !objects.isEmpty()) {
             throw new PCEPDeserializerException("StartTLS message should not contain any objects.");
index 3cc18c60d2c1b638dc2de9d7c94262e5e20c4779..700a6e372551004e38aad76c477b6b06bb62fecf 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.protocol.pcep.parser.util;
 
-import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Object;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.metrics.MetricPce;
@@ -46,21 +46,23 @@ public final class Util {
         }
     }
 
-    public static MetricPce validateMonitoringMetrics(final List<Object> objects) throws PCEPDeserializerException {
-        final MetricPceBuilder metricPceBuilder = new MetricPceBuilder();
-        if (!(objects.get(0) instanceof PceId)) {
+    public static MetricPce validateMonitoringMetrics(final Queue<Object> objects) throws PCEPDeserializerException {
+        final Object pceId = objects.poll();
+        if (!(pceId instanceof PceId)) {
             throw new PCEPDeserializerException("metric-pce-list must start with PCE-ID object.");
         }
-        metricPceBuilder.setPceId((PceId) (objects.get(0)));
-        objects.remove(0);
+
+        final MetricPceBuilder metricPceBuilder = new MetricPceBuilder().setPceId((PceId) pceId);
         State state = State.START;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            final Object obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertObject(metricPceBuilder, state, obj);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         return metricPceBuilder.build();
     }
 
index 2bc7c4429fd242d0bfab49deeec8a6c289078ae4..a4809c46aa511cf6e095c1a5c7463e7e37ba6d62 100644 (file)
@@ -13,6 +13,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -72,7 +73,7 @@ public class InitiatedPCInitiateMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors) {
+    protected Message validate(final Queue<Object> objects, final List<Message> errors) {
         checkArgument(objects != null, "Passed list can't be null.");
         final PcinitiateMessageBuilder builder = new PcinitiateMessageBuilder();
         final List<Requests> reqs = new ArrayList<>();
@@ -83,25 +84,22 @@ public class InitiatedPCInitiateMessageParser extends AbstractMessageParser {
         return new PcinitiateBuilder().setPcinitiateMessage(builder.build()).build();
     }
 
-    protected Requests getValidRequest(final List<Object> objects) {
-        final RequestsBuilder builder = new RequestsBuilder();
-        builder.setSrp((Srp) objects.get(0));
-        objects.remove(0);
-
-        builder.setLsp((Lsp) objects.get(0));
-        objects.remove(0);
+    protected Requests getValidRequest(final Queue<Object> objects) {
+        final RequestsBuilder builder = new RequestsBuilder()
+            .setSrp((Srp) objects.remove())
+            .setLsp((Lsp) objects.remove());
 
         final List<Metrics> metrics = new ArrayList<>();
-
-        Object obj;
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertObject(state, obj, builder, metrics);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         builder.setMetrics(metrics);
         return builder.build();
     }
index bc07451bca0c6d60bade7ae3a8f06186e0034336..13408b798f6bd2075fe7533111c227984e596235 100644 (file)
@@ -13,6 +13,7 @@ import io.netty.buffer.ByteBuf;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.parser.message.PCEPErrorMessageParser;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
@@ -69,48 +70,50 @@ public final class StatefulErrorMessageParser extends PCEPErrorMessageParser {
     }
 
     @Override
-    protected PcerrMessage validate(final List<Object> objects, final List<Message> errors)
+    protected PcerrMessage validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         checkArgument(objects != null, "Passed list can't be null.");
-        if (objects.isEmpty()) {
+
+        final Object first = objects.peek();
+        if (first == null) {
             throw new PCEPDeserializerException("Error message is empty.");
         }
         final List<Rps> requestParameters = new ArrayList<>();
         final List<Srps> srps = new ArrayList<>();
         final List<Errors> errorObjects = new ArrayList<>();
         final PcerrMessageBuilder b = new PcerrMessageBuilder();
-        Object obj = objects.get(0);
         State state = State.INIT;
-        if (obj instanceof ErrorObject) {
-            final ErrorObject o = (ErrorObject) obj;
-            errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
+        if (first instanceof ErrorObject) {
+            errorObjects.add(new ErrorsBuilder().setErrorObject((ErrorObject) first).build());
             state = State.ERROR_IN;
-        } else if (obj instanceof Rp) {
-            final Rp o = (Rp) obj;
-            if (o.getProcessingRule()) {
+        } else if (first instanceof Rp) {
+            final Rp rp = (Rp) first;
+            if (rp.getProcessingRule()) {
                 errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.empty()));
                 return null;
             }
-            requestParameters.add(new RpsBuilder().setRp(o).build());
+            requestParameters.add(new RpsBuilder().setRp(rp).build());
             state = State.RP_IN;
-        } else if (obj instanceof Srp) {
-            final Srp s = (Srp) obj;
-            srps.add(new SrpsBuilder().setSrp(s).build());
+        } else if (first instanceof Srp) {
+            srps.add(new SrpsBuilder().setSrp((Srp) first).build());
             state = State.SRP_IN;
         }
-        if (!state.equals(State.INIT)) {
-            objects.remove(0);
+        if (state != State.INIT) {
+            objects.remove();
         }
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             if (obj instanceof UnknownObject) {
-                return new PcerrBuilder().setPcerrMessage(b.setErrors(((UnknownObject) obj).getErrors()).build())
-                        .build();
+                return new PcerrBuilder()
+                    .setPcerrMessage(b.setErrors(((UnknownObject) obj).getErrors()).build())
+                    .build();
             }
             state = insertObject(state, obj, errorObjects, requestParameters, srps, b);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
         if (errorObjects.isEmpty()) {
             throw new PCEPDeserializerException("At least one PCEPErrorObject is mandatory.");
index ec7c93aba4041ec501470d19e6d667699e663bc2..5ddc8908d6456a8431a21b9d39fd8164924d6690 100644 (file)
@@ -14,6 +14,7 @@ import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -85,7 +86,7 @@ public class StatefulPCReportMessageParser extends AbstractMessageParser {
     }
 
     @Override
-    public Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+    public Message validate(final Queue<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
         checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
             throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
@@ -102,11 +103,11 @@ public class StatefulPCReportMessageParser extends AbstractMessageParser {
         return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
     }
 
-    protected Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+    protected Reports getValidReports(final Queue<Object> objects, final List<Message> errors) {
         final ReportsBuilder builder = new ReportsBuilder();
 
         boolean lspViaSR = false;
-        Object object = objects.remove(0);
+        Object object = objects.remove();
         if (object instanceof Srp) {
             final Srp srp = (Srp) object;
             final Tlvs tlvs = srp.getTlvs();
@@ -114,11 +115,7 @@ public class StatefulPCReportMessageParser extends AbstractMessageParser {
                 lspViaSR = PSTUtil.isDefaultPST(tlvs.getPathSetupType());
             }
             builder.setSrp(srp);
-            if (objects.isEmpty()) {
-                object = null;
-            } else {
-                object = objects.remove(0);
-            }
+            object = objects.poll();
         }
 
         if (validateLsp(object, lspViaSR, errors, builder)) {
@@ -154,10 +151,10 @@ public class StatefulPCReportMessageParser extends AbstractMessageParser {
         return false;
     }
 
-    private static boolean validatePath(final List<Object> objects, final List<Message> errors,
+    private static boolean validatePath(final Queue<Object> objects, final List<Message> errors,
             final ReportsBuilder builder) {
         final PathBuilder pBuilder = new PathBuilder();
-        Object object = objects.remove(0);
+        Object object = objects.remove();
         if (object instanceof Ero) {
             pBuilder.setEro((Ero) object);
         } else {
@@ -169,16 +166,17 @@ public class StatefulPCReportMessageParser extends AbstractMessageParser {
         return true;
     }
 
-    private static void parsePath(final List<Object> objects, final PathBuilder builder) {
+    private static void parsePath(final Queue<Object> objects, final PathBuilder builder) {
         final List<Metrics> pathMetrics = new ArrayList<>();
-        Object obj;
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
+
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
             state = insertObject(state, obj, builder, pathMetrics);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
         if (!pathMetrics.isEmpty()) {
             builder.setMetrics(pathMetrics);
index 0ae4ed1a5fe13879b634b5b6f8454b79a96fb51b..bdca0f91611a44a1a25613b417dbaa4b1ef74a85 100644 (file)
@@ -14,6 +14,7 @@ import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -79,7 +80,7 @@ public class StatefulPCUpdateRequestMessageParser extends AbstractMessageParser
     }
 
     @Override
-    protected Message validate(final List<Object> objects, final List<Message> errors)
+    protected Message validate(final Queue<Object> objects, final List<Message> errors)
             throws PCEPDeserializerException {
         checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
@@ -100,17 +101,13 @@ public class StatefulPCUpdateRequestMessageParser extends AbstractMessageParser
         return new PcupdBuilder().setPcupdMessage(new PcupdMessageBuilder().setUpdates(updateRequests).build()).build();
     }
 
-    protected Updates getValidUpdates(final List<Object> objects, final List<Message> errors) {
+    protected Updates getValidUpdates(final Queue<Object> objects, final List<Message> errors) {
         final UpdatesBuilder builder = new UpdatesBuilder();
 
-        Object object = objects.remove(0);
+        Object object = objects.remove();
         if (object instanceof Srp) {
             builder.setSrp((Srp) object);
-            if (objects.isEmpty()) {
-                object = null;
-            } else {
-                object = objects.remove(0);
-            }
+            object = objects.poll();
         } else {
             errors.add(createErrorMsg(PCEPErrors.SRP_MISSING, Optional.empty()));
         }
@@ -137,10 +134,10 @@ public class StatefulPCUpdateRequestMessageParser extends AbstractMessageParser
         return true;
     }
 
-    private static boolean validatePath(final List<Object> objects, final List<Message> errors,
+    private static boolean validatePath(final Queue<Object> objects, final List<Message> errors,
             final UpdatesBuilder builder) {
         final PathBuilder pBuilder = new PathBuilder();
-        Object object = objects.remove(0);
+        Object object = objects.remove();
         if (object instanceof Ero) {
             pBuilder.setEro((Ero) object);
         } else {
@@ -152,17 +149,18 @@ public class StatefulPCUpdateRequestMessageParser extends AbstractMessageParser
         return true;
     }
 
-    private static void parsePath(final List<Object> objects, final PathBuilder pathBuilder) {
+    private static void parsePath(final Queue<Object> objects, final PathBuilder pathBuilder) {
         final List<Metrics> pathMetrics = new ArrayList<>();
-        Object obj;
         State state = State.INIT;
-        while (!objects.isEmpty() && !state.equals(State.END)) {
-            obj = objects.get(0);
-            state = insertObject(state,obj, pathBuilder, pathMetrics);
-            if (!state.equals(State.END)) {
-                objects.remove(0);
+        for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
+            state = insertObject(state, obj, pathBuilder, pathMetrics);
+            if (state == State.END) {
+                break;
             }
+
+            objects.remove();
         }
+
         if (!pathMetrics.isEmpty()) {
             pathBuilder.setMetrics(pathMetrics);
         }
index e851c8d078a7ee9e65425b6d438e0b752d6116ad..c07d5462c27b44b43a656047ca20bdbd2e766e12 100644 (file)
@@ -11,9 +11,11 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.primitives.UnsignedBytes;
 import io.netty.buffer.ByteBuf;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.protocol.util.BitArray;
 import org.opendaylight.protocol.util.ByteArray;
@@ -64,8 +66,8 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
         }
     }
 
-    private List<Object> parseObjects(final ByteBuf bytes) throws PCEPDeserializerException {
-        final List<Object> objs = new ArrayList<>();
+    private Queue<Object> parseObjects(final ByteBuf bytes) throws PCEPDeserializerException {
+        final Queue<Object> objs = new ArrayDeque<>();
         while (bytes.isReadable()) {
             if (bytes.readableBytes() < COMMON_OBJECT_HEADER_LENGTH) {
                 throw new PCEPDeserializerException("Too few bytes in passed array. Passed: " + bytes.readableBytes()
@@ -120,13 +122,14 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
             .build();
     }
 
-    protected abstract Message validate(List<Object> objects, List<Message> errors) throws PCEPDeserializerException;
+    protected abstract Message validate(Queue<Object> objects, List<Message> errors)
+        throws PCEPDeserializerException;
 
     @Override
     public final Message parseMessage(final ByteBuf buffer, final List<Message> errors)
             throws PCEPDeserializerException {
         // Parse objects first
-        final List<Object> objs = parseObjects(requireNonNull(buffer, "Buffer may not be null"));
+        final Queue<Object> objs = parseObjects(requireNonNull(buffer, "Buffer may not be null"));
 
         // Run validation
         return validate(objs, errors);
@@ -141,12 +144,11 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
         }
     }
 
-    protected static List<VendorInformationObject> addVendorInformationObjects(final List<Object> objects) {
+    protected static List<VendorInformationObject> addVendorInformationObjects(final Queue<Object> objects) {
         final List<VendorInformationObject> vendorInfo = new ArrayList<>();
-        while (!objects.isEmpty() && objects.get(0) instanceof VendorInformationObject) {
-            final VendorInformationObject viObject = (VendorInformationObject) objects.get(0);
-            vendorInfo.add(viObject);
-            objects.remove(0);
+        for (Object obj = objects.peek(); obj instanceof VendorInformationObject; obj = objects.peek()) {
+            vendorInfo.add((VendorInformationObject) obj);
+            objects.remove();
         }
         return vendorInfo;
     }
index e10741712bfcdb34fc0526de6e7410b7ada3b71a..ec424a4839f9f44fa57ae82719b8a997b2e4285d 100644 (file)
@@ -15,13 +15,13 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.only;
 import static org.mockito.Mockito.verify;
 
-import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
+import java.util.Queue;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,16 +65,17 @@ public class AbstractMessageParserTest {
         }
 
         @Override
-        protected Message validate(final List<Object> objects, final List<Message> errors) {
-            if (objects.get(0) instanceof VendorInformationObject) {
+        protected Message validate(final Queue<Object> objects, final List<Message> errors) {
+            final Object obj = objects.element();
+            if (obj instanceof VendorInformationObject) {
                 final RepliesBuilder repsBuilder = new RepliesBuilder();
                 repsBuilder.setVendorInformationObject(addVendorInformationObjects(objects));
                 return new PcrepBuilder().setPcrepMessage(
                     new PcrepMessageBuilder().setReplies(Arrays.asList(repsBuilder.build())).build())
                         .build();
-            } else if (objects.get(0) instanceof ErrorObject) {
-                final Uint8 errorType = ((ErrorObject) objects.get(0)).getType();
-                final Uint8 errorValue = ((ErrorObject) objects.get(0)).getValue();
+            } else if (obj instanceof ErrorObject) {
+                final Uint8 errorType = ((ErrorObject) obj).getType();
+                final Uint8 errorValue = ((ErrorObject) obj).getValue();
                 return createErrorMsg(PCEPErrors.forValue(errorType, errorValue), Optional.empty());
             }
             return null;
@@ -113,7 +114,7 @@ public class AbstractMessageParserTest {
         final Abs parser = new Abs(this.registry);
         final ByteBuf buffer = Unpooled.buffer();
 
-        parser.serializeVendorInformationObjects(Lists.newArrayList(this.viObject), buffer);
+        parser.serializeVendorInformationObjects(List.of(this.viObject), buffer);
         verify(this.registry, only()).serializeVendorInformationObject(any(VendorInformationObject.class),
             any(ByteBuf.class));