BUG-64 : initial rewrite, MessageRegistry.
[bgpcep.git] / pcep / ietf-stateful02 / src / main / java / org / opendaylight / protocol / pcep / ietf / stateful02 / Stateful02PCUpdateRequestMessageParser.java
1 /*
2  * Copyright (c) 2014 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.ietf.stateful02;
9
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.Unpooled;
12
13 import java.util.List;
14
15 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
16 import org.opendaylight.protocol.pcep.spi.MessageUtil;
17 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
18 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
19 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcupd;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PcupdBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.PcupdMessageBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.Updates;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.UpdatesBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.updates.Path;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.updates.PathBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.Bandwidth;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.include.route.object.Iro;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
37
38 import com.google.common.collect.Lists;
39
40 /**
41  * Parser for {@link Pcupd}
42  */
43 public final class Stateful02PCUpdateRequestMessageParser extends AbstractMessageParser {
44
45         public static final int TYPE = 11;
46
47         public Stateful02PCUpdateRequestMessageParser(final ObjectRegistry registry) {
48                 super(registry);
49         }
50
51         @Override
52         public void serializeMessage(final Message message, final ByteBuf out) {
53                 if (!(message instanceof Pcupd)) {
54                         throw new IllegalArgumentException("Wrong instance of PCEPMessage. Passed instance of " + message.getClass()
55                                         + ". Nedded PcupdMessage.");
56                 }
57                 final Pcupd msg = (Pcupd) message;
58                 final List<Updates> updates = msg.getPcupdMessage().getUpdates();
59                 ByteBuf buffer = Unpooled.buffer();
60                 for (final Updates update : updates) {
61                         buffer.writeBytes(serializeObject(update.getLsp()));
62                         final Path p = update.getPath();
63                         if (p != null) {
64                                 buffer.writeBytes(serializeObject(p.getEro()));
65                                 if (p.getLspa() != null) {
66                                         buffer.writeBytes(serializeObject(p.getLspa()));
67                                 }
68                                 if (p.getBandwidth() != null) {
69                                         buffer.writeBytes(serializeObject(p.getBandwidth()));
70                                 }
71                                 if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
72                                         for (final Metrics m : p.getMetrics()) {
73                                                 buffer.writeBytes(serializeObject(m.getMetric()));
74                                         }
75                                 }
76                                 if (p.getIro() != null) {
77                                         buffer.writeBytes(serializeObject(p.getIro()));
78                                 }
79                         }
80                 }
81                 MessageUtil.formatMessage(TYPE, buffer, out);
82         }
83
84         @Override
85         protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
86                 if (objects == null) {
87                         throw new IllegalArgumentException("Passed list can't be null.");
88                 }
89                 if (objects.isEmpty()) {
90                         throw new PCEPDeserializerException("Pcup message cannot be empty.");
91                 }
92
93                 final List<Updates> updateRequests = Lists.newArrayList();
94
95                 while (!objects.isEmpty()) {
96                         final Updates update = getValidUpdates(objects, errors);
97                         if (update != null) {
98                                 updateRequests.add(update);
99                         }
100                 }
101                 if (!objects.isEmpty()) {
102                         throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
103                 }
104                 return new PcupdBuilder().setPcupdMessage(new PcupdMessageBuilder().setUpdates(updateRequests).build()).build();
105         }
106
107         private Updates getValidUpdates(final List<Object> objects, final List<Message> errors) {
108                 final UpdatesBuilder builder = new UpdatesBuilder();
109                 if (objects.get(0) instanceof Lsp) {
110                         builder.setLsp((Lsp) objects.get(0));
111                         objects.remove(0);
112                 } else {
113                         errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
114                         return null;
115                 }
116                 if (!objects.isEmpty()) {
117                         final PathBuilder pBuilder = new PathBuilder();
118                         if (objects.get(0) instanceof Ero) {
119                                 pBuilder.setEro((Ero) objects.get(0));
120                                 objects.remove(0);
121                         } else {
122                                 errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
123                                 return null;
124                         }
125                         parsePath(objects, pBuilder);
126                         builder.setPath(pBuilder.build());
127                 }
128                 return builder.build();
129         }
130
131         private void parsePath(final List<Object> objects, final PathBuilder pBuilder) {
132                 final List<Metrics> pathMetrics = Lists.newArrayList();
133                 Object obj;
134                 State state = State.Init;
135                 while (!objects.isEmpty() && !state.equals(State.End)) {
136                         obj = objects.get(0);
137                         switch (state) {
138                         case Init:
139                                 state = State.LspaIn;
140                                 if (obj instanceof Lspa) {
141                                         pBuilder.setLspa((Lspa) obj);
142                                         break;
143                                 }
144                         case LspaIn:
145                                 state = State.BandwidthIn;
146                                 if (obj instanceof Bandwidth) {
147                                         pBuilder.setBandwidth((Bandwidth) obj);
148                                         break;
149                                 }
150                         case BandwidthIn:
151                                 state = State.MetricIn;
152                                 if (obj instanceof Metric) {
153                                         pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
154                                         state = State.BandwidthIn;
155                                         break;
156                                 }
157                         case MetricIn:
158                                 state = State.IroIn;
159                                 if (obj instanceof Iro) {
160                                         pBuilder.setIro((Iro) obj);
161                                         break;
162                                 }
163                         case IroIn:
164                                 state = State.End;
165                                 break;
166                         case End:
167                                 break;
168                         }
169                         if (!state.equals(State.End)) {
170                                 objects.remove(0);
171                         }
172                 }
173                 if (!pathMetrics.isEmpty()) {
174                         pBuilder.setMetrics(pathMetrics);
175                 }
176         }
177
178         private enum State {
179                 Init, LspaIn, BandwidthIn, MetricIn, IroIn, End
180         }
181
182         @Override
183         public int getMessageType() {
184                 return TYPE;
185         }
186 }