Merge "BUG-2255 : adjusted BGP configuration to use pingpong data broker."
[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 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.spi.AbstractMessageParser;
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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcntfBuilder;
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.PcntfMessage;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.notification.object.CNotification;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.PcntfMessageBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.Notifications;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.NotificationsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Rps;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.RpsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
32
33 /**
34  * Parser for {@link PcntfMessage}
35  */
36 public class PCEPNotificationMessageParser extends AbstractMessageParser {
37
38     public static final int TYPE = 5;
39
40     public PCEPNotificationMessageParser(final ObjectRegistry registry) {
41         super(registry);
42     }
43
44     @Override
45     public void serializeMessage(final Message message, final ByteBuf out) {
46         Preconditions.checkArgument(message instanceof PcntfMessage, "Wrong instance of Message. Passed instance of %s. Need PcntfMessage.", message.getClass());
47         final ByteBuf buffer = Unpooled.buffer();
48         for (final Notifications n : ((PcntfMessage) message).getPcntfMessage().getNotifications()) {
49             if (n.getRps() != null) {
50                 for (final Rps rps : n.getRps()) {
51                     serializeObject(rps.getRp(), buffer);
52                 }
53             }
54             if (n.getNotifications() == null || n.getNotifications().isEmpty()) {
55                 throw new IllegalArgumentException("Message must contain at least one notification object");
56             }
57             for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications not : n.getNotifications()) {
58                 serializeObject(not.getCNotification(), buffer);
59             }
60         }
61         MessageUtil.formatMessage(TYPE, buffer, out);
62     }
63
64     @Override
65     protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
66         if (objects == null) {
67             throw new IllegalArgumentException("Passed list can't be null.");
68         }
69         if (objects.isEmpty()) {
70             throw new PCEPDeserializerException("Notification message cannot be empty.");
71         }
72
73         final List<Notifications> compositeNotifications = new ArrayList<>();
74
75         while (!objects.isEmpty()) {
76             final Notifications comObj = getValidNotificationComposite(objects, errors);
77             if (comObj == null) {
78                 break;
79             }
80             compositeNotifications.add(comObj);
81         }
82         if (compositeNotifications.isEmpty()) {
83             throw new PCEPDeserializerException("Atleast one Notifications is mandatory.");
84         }
85         if (!objects.isEmpty()) {
86             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
87         }
88         return new PcntfBuilder().setPcntfMessage(new PcntfMessageBuilder().setNotifications(compositeNotifications).build()).build();
89     }
90
91     private static Notifications getValidNotificationComposite(final List<Object> objects, final List<Message> errors) {
92         final List<Rps> requestParameters = new ArrayList<>();
93         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.notifications.Notifications> notifications = new ArrayList<>();
94         Object obj;
95
96         State state = State.INIT;
97         while (!objects.isEmpty() && !state.equals(State.END)) {
98             obj = objects.get(0);
99             switch (state) {
100             case INIT:
101                 state = State.RP_IN;
102                 if (obj instanceof Rp) {
103                     final Rp rp = (Rp) obj;
104                     if (rp.isProcessingRule()) {
105                         errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.<Rp>absent()));
106                         return null;
107                     }
108                     requestParameters.add(new RpsBuilder().setRp(rp).build());
109                     state = State.INIT;
110                     break;
111                 }
112             case RP_IN:
113                 state = State.NOTIFICATION_IN;
114                 if (obj instanceof CNotification) {
115                     final CNotification n = (CNotification) obj;
116                     notifications.add(new NotificationsBuilder().setCNotification(n).build());
117                     state = State.RP_IN;
118                     break;
119                 }
120             case NOTIFICATION_IN:
121                 state = State.END;
122                 break;
123             case END:
124                 break;
125             default:
126                 break;
127             }
128             if (!state.equals(State.END)) {
129                 objects.remove(0);
130             }
131         }
132
133         if (notifications.isEmpty()) {
134             return null;
135         }
136
137         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcntf.message.pcntf.message.NotificationsBuilder().setNotifications(
138                 notifications).setRps(requestParameters).build();
139     }
140
141     private enum State {
142         INIT, RP_IN, NOTIFICATION_IN, END
143     }
144 }