2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.parser.impl;
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertThat;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
17 import static org.junit.matchers.JUnitMatchers.containsString;
19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps;
21 import io.netty.buffer.ByteBuf;
22 import io.netty.buffer.Unpooled;
23 import java.net.UnknownHostException;
24 import java.util.Arrays;
25 import java.util.List;
27 import org.junit.BeforeClass;
28 import org.junit.Test;
29 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
30 import org.opendaylight.protocol.bgp.parser.BGPError;
31 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
32 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
33 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
34 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
35 import org.opendaylight.protocol.util.ByteArray;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilities;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilitiesBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.multiprotocol._case.MultiprotocolCapabilityBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
56 import org.opendaylight.yangtools.yang.binding.Notification;
58 public class ParserTest {
60 private static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
61 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
62 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
63 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
65 private static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
66 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
67 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
69 private static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
70 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
71 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
73 private static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
74 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
75 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
76 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
77 (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x40,
78 (byte) 0x04, (byte) 0x00, (byte) 0x47 };
80 private static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
81 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
82 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
83 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
84 (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47, (byte) 0x01, (byte) 0x04, (byte) 0x00,
85 (byte) 0x01, (byte) 0x00, (byte) 0x01 };
87 private static final byte[] updMsgWithUnrecognizedAttribute = new byte[] {
88 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
89 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02,
90 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47, (byte) 0x04, (byte) 0x0a, (byte) 0x19,
91 (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
92 (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, (byte)0x01,
93 (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
94 (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x64,
95 (byte) 0x80, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
96 (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
99 static MessageRegistry reg;
102 public static void setupClass() throws Exception {
103 reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
107 public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
108 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
109 wrong = ByteArray.cutBytes(wrong, 16);
111 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
112 fail("Exception should have occcured.");
113 } catch (final IllegalArgumentException e) {
114 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage());
121 public void testBadMsgType() throws BGPParsingException {
122 final byte[] bytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
123 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
124 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
126 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
127 fail("Exception should have occured.");
128 } catch (final BGPDocumentedException e) {
129 assertEquals(BGPError.BAD_MSG_TYPE, e.getError());
136 public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
137 final Notification keepAlive = new KeepaliveBuilder().build();
138 final ByteBuf buffer = Unpooled.buffer();
139 ParserTest.reg.serializeMessage(keepAlive, buffer);
140 assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
142 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)));
144 assertTrue(m instanceof Keepalive);
148 public void testBadKeepAliveMsg() throws BGPParsingException {
149 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
150 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
151 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
154 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
155 fail("Exception should have occured.");
156 } catch (final BGPDocumentedException e) {
157 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
158 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
165 public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
166 final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
167 new ProtocolVersion((short) 4)).build();
168 final ByteBuf bytes = Unpooled.buffer();
169 ParserTest.reg.serializeMessage(open, bytes);
170 assertArrayEquals(openBMsg, ByteArray.getAllBytes(bytes));
172 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
174 assertTrue(m instanceof Open);
175 assertEquals(100, ((Open) m).getMyAsNumber().intValue());
176 assertEquals(180, ((Open) m).getHoldTimer().intValue());
177 assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier());
178 assertTrue(((Open) m).getBgpParameters().isEmpty());
182 public void testBadHoldTimeError() throws BGPParsingException {
183 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
184 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
185 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
186 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
189 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
190 fail("Exception should have occured.");
191 } catch (final BGPDocumentedException e) {
192 assertEquals("Hold time value not acceptable.", e.getMessage());
193 assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError());
200 public void testBadMsgLength() throws BGPParsingException {
201 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
202 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
203 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
204 (byte) 0xff, (byte) 0xff };
207 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
208 fail("Exception should have occured.");
209 } catch (final BGPDocumentedException e) {
210 assertEquals("Open message too small.", e.getMessage());
211 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
216 public void testBadVersion() throws BGPParsingException {
217 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
218 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
219 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
220 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
223 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
224 fail("Exception should have occured.");
225 } catch (final BGPDocumentedException e) {
226 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
227 assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError());
234 public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
235 Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
236 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
237 final ByteBuf bytes = Unpooled.buffer();
238 ParserTest.reg.serializeMessage(notMsg, bytes);
239 assertArrayEquals(notificationBMsg, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
241 Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
243 assertTrue(m instanceof Notify);
244 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
245 assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData());
247 notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
248 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
252 ParserTest.reg.serializeMessage(notMsg, bytes);
254 m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
256 assertTrue(m instanceof Notify);
257 assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
258 assertNull(((Notify) m).getData());
262 public void testWrongLength() throws BGPParsingException {
263 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
264 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
265 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
268 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
269 fail("Exception should have occured.");
270 } catch (final BGPDocumentedException e) {
271 assertEquals("Notification message too small.", e.getMessage());
272 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
279 public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException {
280 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
281 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
282 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
285 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
286 fail("Exception should have occured.");
287 } catch (final IllegalArgumentException e) {
288 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
295 public void testTLVParser() throws UnknownHostException {
297 final BgpTableType t1 = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
298 final BgpTableType t2 = new BgpTableTypeImpl(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
300 final List<OptionalCapabilities> capas = Lists.newArrayList();
302 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
303 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
304 new MultiprotocolCapabilityBuilder().setAfi(LinkstateAddressFamily.class).setSafi(
305 LinkstateSubsequentAddressFamily.class).build()).build()).build());
306 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
307 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
308 new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).build()).build()).build());
309 final List<BgpParameters> tlvs = Lists.newArrayList(new BgpParametersBuilder().setOptionalCapabilities(capas).build());
311 final Map<BgpTableType, Boolean> tableTypes = Maps.newHashMap();
312 tableTypes.put(t1, true);
313 tableTypes.put(t2, true);
314 final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion(
315 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
317 final ByteBuf result = Unpooled.buffer();
318 ParserTest.reg.serializeMessage(open, result);
320 // the capabilities can be swapped.
321 assertTrue(Arrays.equals(openWithCpblt1, ByteArray.getAllBytes(result)) || Arrays.equals(openWithCpblt2, ByteArray.getAllBytes(result)));
325 public void testParseUpdMsgWithUnrecognizedAttribute() throws BGPDocumentedException, BGPParsingException {
326 final Update updMsg = (Update) reg.parseMessage(Unpooled.copiedBuffer(updMsgWithUnrecognizedAttribute));
327 assertNotNull(updMsg.getPathAttributes());