Fix for commit 75b14cd92b9f5bb4ced99fae55b3fcdd7236c2d4.
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / message / PCEPReportMessageParser.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.pcep.impl.message;
9
10 import io.netty.buffer.ByteBuf;
11
12 import java.util.List;
13
14 import org.opendaylight.protocol.pcep.PCEPDeserializerException;
15 import org.opendaylight.protocol.pcep.PCEPDocumentedException;
16 import org.opendaylight.protocol.pcep.PCEPErrors;
17 import org.opendaylight.protocol.pcep.UnknownObject;
18 import org.opendaylight.protocol.pcep.impl.AbstractMessageParser;
19 import org.opendaylight.protocol.pcep.spi.ObjectHandlerRegistry;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcrpt;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcrptBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.Bandwidth;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.include.route.object.Iro;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.object.Lsp;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.PcrptMessageBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.Reports;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.ReportsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.reports.Path;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.reports.PathBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.Rro;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.srp.object.Srp;
39
40 import com.google.common.collect.Lists;
41
42 /**
43  * Parser for {@link Pcrpt}
44  */
45 public class PCEPReportMessageParser extends AbstractMessageParser {
46
47         public static final int TYPE = 10;
48
49         public PCEPReportMessageParser(final ObjectHandlerRegistry registry) {
50                 super(registry);
51         }
52
53         @Override
54         public void serializeMessage(final Message message, final ByteBuf buffer) {
55                 if (!(message instanceof Pcrpt)) {
56                         throw new IllegalArgumentException("Wrong instance of Message. Passed instance of " + message.getClass()
57                                         + ". Nedded PcrptMessage.");
58                 }
59                 final Pcrpt msg = (Pcrpt) message;
60                 final List<Reports> reports = msg.getPcrptMessage().getReports();
61                 for (final Reports report : reports) {
62                         if (report.getSrp() != null) {
63                                 buffer.writeBytes(serializeObject(report.getSrp()));
64                         }
65                         buffer.writeBytes(serializeObject(report.getLsp()));
66                         final Path p = report.getPath();
67                         if (p.getEro() != null) {
68                                 buffer.writeBytes(serializeObject(p.getEro()));
69                         }
70                         if (p.getBandwidth() != null) {
71                                 buffer.writeBytes(serializeObject(p.getBandwidth()));
72                         }
73                         if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
74                                 for (final Metrics m : p.getMetrics()) {
75                                         buffer.writeBytes(serializeObject(m.getMetric()));
76                                 }
77                         }
78                         if (p.getIro() != null) {
79                                 buffer.writeBytes(serializeObject(p.getIro()));
80                         }
81                         if (p.getRro() != null) {
82                                 buffer.writeBytes(serializeObject(p.getRro()));
83                         }
84                 }
85         }
86
87         @Override
88         public Message parseMessage(final byte[] buffer) throws PCEPDeserializerException {
89                 if (buffer == null || buffer.length == 0) {
90                         throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
91                 }
92                 try {
93                         final List<Object> objs = parseObjects(buffer);
94                         return validate(objs);
95                 } catch (final PCEPDocumentedException e) {
96                         return createErrorMsg(e.getError());
97                 }
98         }
99
100         public Pcrpt validate(final List<Object> objects) throws PCEPDeserializerException, PCEPDocumentedException {
101                 if (objects == null) {
102                         throw new IllegalArgumentException("Passed list can't be null.");
103                 }
104
105                 final List<Reports> reports = Lists.newArrayList();
106
107                 while (!objects.isEmpty()) {
108                         final Reports report = getValidReports(objects);
109                         reports.add(report);
110                 }
111
112                 if (!objects.isEmpty()) {
113                         if (objects.get(0) instanceof UnknownObject) {
114                                 throw new PCEPDocumentedException("Unknown object encountered", ((UnknownObject) objects.get(0)).getError());
115                         }
116                         throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
117                 }
118                 return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
119         }
120
121         private Reports getValidReports(final List<Object> objects) throws PCEPDocumentedException {
122                 Srp srp = null;
123                 Lsp lsp = null;
124                 Ero ero = null;
125                 Lspa pathLspa = null;
126                 Bandwidth pathBandwidth = null;
127                 final List<Metrics> pathMetrics = Lists.newArrayList();
128                 Rro pathRro = null;
129                 Iro iro = null;
130
131                 Object obj;
132                 State state = State.Init;
133                 while (!objects.isEmpty()) {
134                         obj = objects.get(0);
135                         if (obj instanceof UnknownObject) {
136                                 throw new PCEPDocumentedException("Unknown object", ((UnknownObject) obj).getError());
137                         }
138                         switch (state) {
139                         case Init:
140                                 state = State.SrpIn;
141                                 if (obj instanceof Srp) {
142                                         srp = (Srp) obj;
143                                         break;
144                                 }
145                         case SrpIn:
146                                 state = State.LspIn;
147                                 if (obj instanceof Lsp) {
148                                         lsp = (Lsp) obj;
149                                         break;
150                                 }
151                         case EroIn:
152                                 state = State.LspaIn;
153                                 if (obj instanceof Ero) {
154                                         ero = (Ero) obj;
155                                         break;
156                                 }
157                         case LspaIn:
158                                 state = State.BandwidthIn;
159                                 if (obj instanceof Lspa) {
160                                         pathLspa = (Lspa) obj;
161                                         break;
162                                 }
163                         case BandwidthIn:
164                                 state = State.MetricIn;
165                                 if (obj instanceof Bandwidth) {
166                                         pathBandwidth = (Bandwidth) obj;
167                                         break;
168                                 }
169                         case MetricIn:
170                                 state = State.IroIn;
171                                 if (obj instanceof Metric) {
172                                         pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
173                                         state = State.MetricIn;
174                                         break;
175                                 }
176                         case IroIn:
177                                 state = State.RroIn;
178                                 if (obj instanceof Iro) {
179                                         iro = (Iro) obj;
180                                         break;
181                                 }
182                         case RroIn:
183                                 state = State.End;
184                                 if (obj instanceof Rro) {
185                                         pathRro = (Rro) obj;
186                                         break;
187                                 }
188                         case End:
189                                 break;
190                         default:
191                                 if (obj instanceof UnknownObject) {
192                                         throw new PCEPDocumentedException("Unknown object", ((UnknownObject) obj).getError());
193                                 }
194                         }
195                         objects.remove(0);
196                 }
197                 if (lsp == null) {
198                         throw new PCEPDocumentedException("LSP object missing", PCEPErrors.LSP_MISSING);
199                 }
200
201                 final PathBuilder builder = new PathBuilder();
202                 builder.setEro(ero);
203                 builder.setLspa(pathLspa);
204                 builder.setBandwidth(pathBandwidth);
205                 builder.setMetrics(pathMetrics);
206                 builder.setIro(iro);
207                 builder.setRro(pathRro);
208                 return new ReportsBuilder().setSrp(srp).setLsp(lsp).setPath(builder.build()).build();
209         }
210
211         private enum State {
212                 Init, SrpIn, LspIn, EroIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
213         }
214
215         @Override
216         public int getMessageType() {
217                 return TYPE;
218         }
219 }