BUG-50 : added parser for Pcreq message.
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / message / PCEPNotificationMessageParser.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.spi.ObjectHandlerRegistry;
15 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
16 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcntfBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcntfMessage;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.notification.object.CNotification;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.PcntfMessageBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.NotificationsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Rps;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.RpsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
28
29 import com.google.common.collect.Lists;
30
31 /**
32  * Parser for {@link PcntfMessage}
33  */
34 public class PCEPNotificationMessageParser extends AbstractMessageParser {
35
36         public static final int TYPE = 5;
37
38         public PCEPNotificationMessageParser(final ObjectHandlerRegistry registry) {
39                 super(registry);
40         }
41
42         @Override
43         public void serializeMessage(final Message message, final ByteBuf buffer) {
44                 if (!(message instanceof PcntfMessage)) {
45                         throw new IllegalArgumentException("Wrong instance of Message. Passed instance of " + message.getClass()
46                                         + ". Needed PcntfMessage.");
47                 }
48                 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.PcntfMessage msg = ((PcntfMessage) message).getPcntfMessage();
49
50                 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications n : msg.getNotifications()) {
51                         if (n.getRps() != null && !n.getRps().isEmpty()) {
52                                 for (final Rps rps : n.getRps()) {
53                                         buffer.writeBytes(serializeObject(rps.getRp()));
54                                 }
55                         }
56                         if (n.getNotifications() == null || n.getNotifications().isEmpty()) {
57                                 throw new IllegalArgumentException("Message must contain at least one notification object");
58                         } else {
59                                 for (final Notifications not : n.getNotifications()) {
60                                         buffer.writeBytes(serializeObject(not.getCNotification()));
61                                 }
62                         }
63                 }
64         }
65
66         @Override
67         protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
68                 if (objects == null) {
69                         throw new IllegalArgumentException("Passed list can't be null.");
70                 }
71                 if (objects.isEmpty()) {
72                         throw new PCEPDeserializerException("Notification message cannot be empty.");
73                 }
74
75                 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications> compositeNotifications = Lists.newArrayList();
76
77                 while (!objects.isEmpty()) {
78                         org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications comObj;
79                         comObj = getValidNotificationComposite(objects, errors);
80
81                         if (comObj == null) {
82                                 break;
83                         }
84                         compositeNotifications.add(comObj);
85                 }
86                 if (compositeNotifications.isEmpty()) {
87                         throw new PCEPDeserializerException("Atleast one Notifications is mandatory.");
88                 }
89                 if (!objects.isEmpty()) {
90                         throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
91                 }
92                 return new PcntfBuilder().setPcntfMessage(new PcntfMessageBuilder().setNotifications(compositeNotifications).build()).build();
93         }
94
95         private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications getValidNotificationComposite(
96                         final List<Object> objects, final List<Message> errors) {
97                 final List<Rps> requestParameters = Lists.newArrayList();
98                 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications> notifications = Lists.newArrayList();
99                 Object obj;
100
101                 State state = State.Init;
102                 while (!objects.isEmpty() && !state.equals(State.End)) {
103                         obj = objects.get(0);
104                         switch (state) {
105                         case Init:
106                                 state = State.RpIn;
107                                 if (obj instanceof Rp) {
108                                         final Rp rp = (Rp) obj;
109                                         if (rp.isProcessingRule()) {
110                                                 errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET));
111                                                 return null;
112                                         }
113                                         requestParameters.add(new RpsBuilder().setRp(rp).build());
114                                         state = State.Init;
115                                         break;
116                                 }
117                         case RpIn:
118                                 state = State.NotificationIn;
119                                 if (obj instanceof CNotification) {
120                                         final CNotification n = (CNotification) obj;
121                                         notifications.add(new NotificationsBuilder().setCNotification(n).build());
122                                         state = State.RpIn;
123                                         break;
124                                 }
125                         case NotificationIn:
126                                 state = State.End;
127                                 break;
128                         case End:
129                                 break;
130                         }
131                         if (!state.equals(State.End)) {
132                                 objects.remove(0);
133                         }
134                 }
135
136                 if (notifications.isEmpty()) {
137                         return null;
138                 }
139
140                 return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.NotificationsBuilder().setNotifications(
141                                 notifications).setRps(requestParameters).build();
142         }
143
144         private enum State {
145                 Init, RpIn, NotificationIn, End
146         }
147
148         @Override
149         public int getMessageType() {
150                 return TYPE;
151         }
152 }