Rework PCEPDeserializerException and move it into SPI
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / message / PCEPReportMessageParser.java
index a450366433999f51e044cb5429d591541ac74896..6ff635f17a062308f61f205ee38274f8dee991d6 100644 (file)
@@ -11,12 +11,9 @@ import io.netty.buffer.ByteBuf;
 
 import java.util.List;
 
-import org.opendaylight.protocol.pcep.PCEPDeserializerException;
-import org.opendaylight.protocol.pcep.PCEPDocumentedException;
-import org.opendaylight.protocol.pcep.PCEPErrors;
-import org.opendaylight.protocol.pcep.UnknownObject;
-import org.opendaylight.protocol.pcep.impl.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.ObjectHandlerRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcrpt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcrptBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
@@ -64,152 +61,133 @@ public class PCEPReportMessageParser extends AbstractMessageParser {
                        }
                        buffer.writeBytes(serializeObject(report.getLsp()));
                        final Path p = report.getPath();
-                       if (p.getEro() != null) {
-                               buffer.writeBytes(serializeObject(p.getEro()));
-                       }
-                       if (p.getBandwidth() != null) {
-                               buffer.writeBytes(serializeObject(p.getBandwidth()));
-                       }
-                       if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
-                               for (final Metrics m : p.getMetrics()) {
-                                       buffer.writeBytes(serializeObject(m.getMetric()));
+                       if (p != null) {
+                               if (p.getEro() != null) {
+                                       buffer.writeBytes(serializeObject(p.getEro()));
+                               }
+                               if (p.getLspa() != null) {
+                                       buffer.writeBytes(serializeObject(p.getLspa()));
+                               }
+                               if (p.getBandwidth() != null) {
+                                       buffer.writeBytes(serializeObject(p.getBandwidth()));
+                               }
+                               if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+                                       for (final Metrics m : p.getMetrics()) {
+                                               buffer.writeBytes(serializeObject(m.getMetric()));
+                                       }
+                               }
+                               if (p.getIro() != null) {
+                                       buffer.writeBytes(serializeObject(p.getIro()));
+                               }
+                               if (p.getRro() != null) {
+                                       buffer.writeBytes(serializeObject(p.getRro()));
                                }
-                       }
-                       if (p.getIro() != null) {
-                               buffer.writeBytes(serializeObject(p.getIro()));
-                       }
-                       if (p.getRro() != null) {
-                               buffer.writeBytes(serializeObject(p.getRro()));
                        }
                }
        }
 
        @Override
-       public Message parseMessage(final byte[] buffer) throws PCEPDeserializerException {
-               if (buffer == null || buffer.length == 0) {
-                       throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
-               }
-               try {
-                       final List<Object> objs = parseObjects(buffer);
-                       return validate(objs);
-               } catch (final PCEPDocumentedException e) {
-                       return createErrorMsg(e.getError());
-               }
-       }
-
-       public Pcrpt validate(final List<Object> objects) throws PCEPDeserializerException, PCEPDocumentedException {
+       public Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
                if (objects == null) {
                        throw new IllegalArgumentException("Passed list can't be null.");
                }
+               if (objects.isEmpty()) {
+                       throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
+               }
 
                final List<Reports> reports = Lists.newArrayList();
 
                while (!objects.isEmpty()) {
-                       final Reports report = getValidReports(objects);
-                       reports.add(report);
+                       final Reports report = getValidReports(objects, errors);
+                       if (reports != null) {
+                               reports.add(report);
+                       }
                }
+               return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
+       }
 
+       private Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+               final ReportsBuilder builder = new ReportsBuilder();
+               if (objects.get(0) instanceof Srp) {
+                       builder.setSrp((Srp) objects.get(0));
+                       objects.remove(0);
+               }
+               if (objects.get(0) instanceof Lsp) {
+                       builder.setLsp((Lsp) objects.get(0));
+                       objects.remove(0);
+               } else {
+                       errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+                       return null;
+               }
                if (!objects.isEmpty()) {
-                       if (objects.get(0) instanceof UnknownObject) {
-                               throw new PCEPDocumentedException("Unknown object encountered", ((UnknownObject) objects.get(0)).getError());
-                       }
-                       throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
+                       final PathBuilder pBuilder = new PathBuilder();
+                       parsePath(objects, pBuilder);
+                       builder.setPath(pBuilder.build());
                }
-               return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
+               return builder.build();
        }
 
-       private Reports getValidReports(final List<Object> objects) throws PCEPDocumentedException {
-               Srp srp = null;
-               Lsp lsp = null;
-               Ero ero = null;
-               Lspa pathLspa = null;
-               Bandwidth pathBandwidth = null;
+       private void parsePath(final List<Object> objects, final PathBuilder builder) {
                final List<Metrics> pathMetrics = Lists.newArrayList();
-               Rro pathRro = null;
-               Iro iro = null;
-
                Object obj;
                State state = State.Init;
-               while (!objects.isEmpty()) {
+               while (!objects.isEmpty() && !state.equals(State.End)) {
                        obj = objects.get(0);
-                       if (obj instanceof UnknownObject) {
-                               throw new PCEPDocumentedException("Unknown object", ((UnknownObject) obj).getError());
-                       }
                        switch (state) {
                        case Init:
-                               state = State.SrpIn;
-                               if (obj instanceof Srp) {
-                                       srp = (Srp) obj;
-                                       break;
-                               }
-                       case SrpIn:
-                               state = State.LspIn;
-                               if (obj instanceof Lsp) {
-                                       lsp = (Lsp) obj;
+                               state = State.EroIn;
+                               if (obj instanceof Ero) {
+                                       builder.setEro((Ero) obj);
                                        break;
                                }
                        case EroIn:
                                state = State.LspaIn;
-                               if (obj instanceof Ero) {
-                                       ero = (Ero) obj;
+                               if (obj instanceof Lspa) {
+                                       builder.setLspa((Lspa) obj);
                                        break;
                                }
                        case LspaIn:
                                state = State.BandwidthIn;
-                               if (obj instanceof Lspa) {
-                                       pathLspa = (Lspa) obj;
+                               if (obj instanceof Bandwidth) {
+                                       builder.setBandwidth((Bandwidth) obj);
                                        break;
                                }
                        case BandwidthIn:
                                state = State.MetricIn;
-                               if (obj instanceof Bandwidth) {
-                                       pathBandwidth = (Bandwidth) obj;
+                               if (obj instanceof Metric) {
+                                       pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
+                                       state = State.BandwidthIn;
                                        break;
                                }
                        case MetricIn:
                                state = State.IroIn;
-                               if (obj instanceof Metric) {
-                                       pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
-                                       state = State.MetricIn;
+                               if (obj instanceof Iro) {
+                                       builder.setIro((Iro) obj);
                                        break;
                                }
                        case IroIn:
                                state = State.RroIn;
-                               if (obj instanceof Iro) {
-                                       iro = (Iro) obj;
+                               if (obj instanceof Rro) {
+                                       builder.setRro((Rro) obj);
                                        break;
                                }
                        case RroIn:
                                state = State.End;
-                               if (obj instanceof Rro) {
-                                       pathRro = (Rro) obj;
-                                       break;
-                               }
+                               break;
                        case End:
                                break;
-                       default:
-                               if (obj instanceof UnknownObject) {
-                                       throw new PCEPDocumentedException("Unknown object", ((UnknownObject) obj).getError());
-                               }
                        }
-                       objects.remove(0);
+                       if (!state.equals(State.End)) {
+                               objects.remove(0);
+                       }
                }
-               if (lsp == null) {
-                       throw new PCEPDocumentedException("LSP object missing", PCEPErrors.LSP_MISSING);
+               if (!pathMetrics.isEmpty()) {
+                       builder.setMetrics(pathMetrics);
                }
-
-               final PathBuilder builder = new PathBuilder();
-               builder.setEro(ero);
-               builder.setLspa(pathLspa);
-               builder.setBandwidth(pathBandwidth);
-               builder.setMetrics(pathMetrics);
-               builder.setIro(iro);
-               builder.setRro(pathRro);
-               return new ReportsBuilder().setSrp(srp).setLsp(lsp).setPath(builder.build()).build();
        }
 
        private enum State {
-               Init, SrpIn, LspIn, EroIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
+               Init, EroIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
        }
 
        @Override