0ce108f0e541ceebebd9ce4288cbc060c8331621
[bgpcep.git] / pcep / ietf-stateful07 / src / main / java / org / opendaylight / protocol / pcep / ietf / stateful07 / Stateful07ErrorMessageParser.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.ietf.stateful07;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.protocol.pcep.impl.message.PCEPErrorMessageParser;
17 import org.opendaylight.protocol.pcep.spi.MessageUtil;
18 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
19 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
20 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
21 import org.opendaylight.protocol.pcep.spi.UnknownObject;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.StatefulCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.StatefulCaseBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.stateful._case.StatefulBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.stateful._case.stateful.Srps;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcerr.pcerr.message.error.type.stateful._case.stateful.SrpsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.Srp;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcerrMessage;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObject;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.Errors;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.ErrorsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.RequestCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.RequestCaseBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.SessionCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.SessionCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.request._case.request.Rps;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.request._case.request.RpsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.session._case.SessionBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
46
47 /**
48  * Parser for {@link PcerrMessage}
49  */
50 public final class Stateful07ErrorMessageParser extends PCEPErrorMessageParser {
51
52     public Stateful07ErrorMessageParser(final ObjectRegistry registry) {
53         super(registry);
54     }
55
56     @Override
57     public void serializeMessage(final Message message, final ByteBuf out) {
58         Preconditions.checkArgument(message instanceof PcerrMessage, "Wrong instance of Message. Passed instance of %s. Need ErrorMessage.", message.getClass());
59         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessage err = ((PcerrMessage) message).getPcerrMessage();
60
61         if (err.getErrors() == null || err.getErrors().isEmpty()) {
62             throw new IllegalArgumentException("Errors should not be empty.");
63         }
64         final ByteBuf buffer = Unpooled.buffer();
65
66         if (err.getErrorType() instanceof RequestCase) {
67             final List<Rps> rps = ((RequestCase) err.getErrorType()).getRequest().getRps();
68             for (final Rps r : rps) {
69                 serializeObject(r.getRp(), buffer);
70             }
71         }
72         if (err.getErrorType() instanceof StatefulCase) {
73             final List<Srps> srps = ((StatefulCase) err.getErrorType()).getStateful().getSrps();
74             for (final Srps s : srps) {
75                 serializeObject(s.getSrp(), buffer);
76             }
77         }
78         for (final Errors e : err.getErrors()) {
79             serializeObject(e.getErrorObject(), buffer);
80         }
81         if (err.getErrorType() instanceof SessionCase) {
82             serializeObject(((SessionCase) err.getErrorType()).getSession().getOpen(), buffer);
83         }
84         MessageUtil.formatMessage(TYPE, buffer, out);
85     }
86
87     @Override
88     protected PcerrMessage validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
89         if (objects == null) {
90             throw new IllegalArgumentException("Passed list can't be null.");
91         }
92         if (objects.isEmpty()) {
93             throw new PCEPDeserializerException("Error message is empty.");
94         }
95
96         final List<Rps> requestParameters = new ArrayList<>();
97         final List<Srps> srps = new ArrayList<>();
98         final List<Errors> errorObjects = new ArrayList<>();
99         final PcerrMessageBuilder b = new PcerrMessageBuilder();
100
101         Object obj;
102         State state = State.Init;
103         obj = objects.get(0);
104
105         if (obj instanceof ErrorObject) {
106             final ErrorObject o = (ErrorObject) obj;
107             errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
108             state = State.ErrorIn;
109             objects.remove(0);
110         } else if (obj instanceof Rp) {
111             final Rp o = (Rp) obj;
112             if (o.isProcessingRule()) {
113                 errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.<Rp>absent()));
114                 return null;
115             }
116             requestParameters.add(new RpsBuilder().setRp(o).build());
117             state = State.RpIn;
118             objects.remove(0);
119         } else if (obj instanceof Srp) {
120             final Srp s = (Srp) obj;
121             srps.add(new SrpsBuilder().setSrp(s).build());
122             state = State.SrpIn;
123             objects.remove(0);
124         }
125
126         while (!objects.isEmpty()) {
127             obj = objects.get(0);
128
129             if (obj instanceof UnknownObject) {
130                 return new PcerrBuilder().setPcerrMessage(b.setErrors(((UnknownObject) obj).getErrors()).build()).build();
131             }
132
133             switch (state) {
134             case ErrorIn:
135                 state = State.Open;
136                 if (obj instanceof ErrorObject) {
137                     final ErrorObject o = (ErrorObject) obj;
138                     errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
139                     state = State.ErrorIn;
140                     break;
141                 }
142             case RpIn:
143                 state = State.Error;
144                 if (obj instanceof Rp) {
145                     final Rp o = ((Rp) obj);
146                     requestParameters.add(new RpsBuilder().setRp(o).build());
147                     state = State.RpIn;
148                     break;
149                 }
150             case SrpIn:
151                 state = State.Error;
152                 if (obj instanceof Srp) {
153                     final Srp o = ((Srp) obj);
154                     srps.add(new SrpsBuilder().setSrp(o).build());
155                     state = State.SrpIn;
156                     break;
157                 }
158             case Open:
159                 state = State.OpenIn;
160                 if (obj instanceof Open) {
161                     b.setErrorType(new SessionCaseBuilder().setSession(new SessionBuilder().setOpen((Open) obj).build()).build());
162                     break;
163                 }
164             case Error:
165                 state = State.OpenIn;
166                 if (obj instanceof ErrorObject) {
167                     final ErrorObject o = (ErrorObject) obj;
168                     errorObjects.add(new ErrorsBuilder().setErrorObject(o).build());
169                     state = State.Error;
170                     break;
171                 }
172             case OpenIn:
173                 state = State.End;
174                 break;
175             case End:
176                 break;
177             default:
178                 break;
179             }
180             if (!state.equals(State.End)) {
181                 objects.remove(0);
182             }
183         }
184
185         if (errorObjects.isEmpty()) {
186             throw new PCEPDeserializerException("At least one PCEPErrorObject is mandatory.");
187         }
188
189         if (!objects.isEmpty()) {
190             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
191         }
192         if (!requestParameters.isEmpty()) {
193             b.setErrorType(new RequestCaseBuilder().setRequest(new RequestBuilder().setRps(requestParameters).build()).build());
194         }
195         if (!srps.isEmpty()) {
196             b.setErrorType(new StatefulCaseBuilder().setStateful(new StatefulBuilder().setSrps(srps).build()).build());
197         }
198
199         return new PcerrBuilder().setPcerrMessage(b.setErrors(errorObjects).build()).build();
200     }
201
202     private enum State {
203         Init, ErrorIn, RpIn, SrpIn, Open, Error, OpenIn, End
204     }
205 }