Merge "Documentation outline for for usc"
[docs.git] / manuals / developer-guide / src / main / asciidoc / bgpcep.adoc
1 ==  BGP LS PCEP
2
3 === BGPCEP Overview 
4
5 An extension to a protocol means adding parsers and serializers for new elements, such as messages, objects, TLVs or subobjects. 
6 This is necessary when you are extending the protocol with another RFC or draft. Both BGP and PCEP parsers are pluggable and you can specify which extensions to load alongside to the base parser in the configuration file.
7
8 Writing an extension to PCE protocol
9 Current standards support
10 Current pcep base-parser implementation supports following RFCs: +
11
12 http://tools.ietf.org/html/rfc5440[RFC5440] - Path Computation Element (PCE) Communication Protocol (PCEP) +
13 http://tools.ietf.org/html/rfc5541[RFC5541] - Encoding of Objective Functions in the Path Computation Element Communication Protocol (PCEP) +
14 http://tools.ietf.org/html/rfc5455[RFC5455] - Diffserv-Aware Class-Type Object for the Path Computation Element Communication Protocol +
15 http://tools.ietf.org/html/rfc5521[RFC5521] - Extensions to the Path Computation Element Communication Protocol (PCEP) for Route Exclusions +
16 http://tools.ietf.org/html/rfc5557[RFC5557] - Path Computation Element Communication Protocol (PCEP) Requirements and Protocol Extensions in Support of Global Concurrent Optimization +
17
18 There are already two extensions for: +
19 https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-09[draft-ietf-pce-stateful-pce] - in versions 02 and 07 +
20 https://tools.ietf.org/html/draft-ietf-pce-pce-initiated-lsp-01[draft-ietf-pce-pce-initiated-lsp] - versions crabbe-initiated-00 and ietf-initiated-00 
21
22
23 [literal]
24
25 dependency>
26     <groupId>${project.groupId}</groupId>
27     <artifactId>pcep-ietf-stateful02</artifactId>
28 </dependency>
29
30 [literal]
31
32 <dependency>
33     <groupId>${project.groupId}</groupId>
34     <artifactId>pcep-ietf-stateful07</artifactId>
35 </dependency>
36
37 NOTE: It is important to load the extensions with compatible versions because that they extend each other. In this case crabbe-initiated-00 is compatible with stateful-02 and ietf-initiated-00 is compatible with stateful-07.
38
39 === Implementing an Extension to PCEP
40
41 To implement an extension of PCEP: +
42
43 . Create a separate artefact (eclipse project) for your extension. +
44 Ensure the dependency on pcep-api and pcep-spi.
45 . Write YANG model for new elements or augment existing ones. 
46 . Perform `mvn install` to generate files from the model.
47 . Write parsers and serializers. All parsers need to implement *Parser and *Serializer interfaces from pcep-spi, (For example: If you are writing a new TLV, your parser must implement TlvParser and TlvSerializer), add Activator, that extends AbstractPCEPExtensionProviderActivator, where you register your parsers and serializers.
48
49 === Update Configuration
50 Update [32-pcep.xml]. Register your parser as a module in pcep-impl: +
51
52 [literal]
53 <module>
54         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:impl">
55                 prefix:pcep-parser-new-parser
56         </type>
57         <name>pcep-parser-new-parser</name>
58 </module>
59
60 * Add it as an extension to pcep-parser-base:
61
62 [literal]
63 <extension>
64         <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
65                 pcepspi:extension
66         </type>
67         <name>pcep-parser-new-parser</name>
68 </extension>
69
70 * Add the instance to services:
71
72 [literal]
73 <instance>
74         <name>pcep-parser-new-parser</name>
75         <provider>/config/modules/module[name='pcep-parser-new-parser']/instance[name='pcep-parser-new-parser']</provider>
76 </instance>
77
78 * Update `odl-pcep-impl-cfg.yang` so that it generates Module and ModuleFactory classes for your new parser.
79
80 [literal]
81 identity pcep-parser-new-parser {
82         base config:module-type;
83         config:provided-service spi:extension;
84         config:java-name-prefix NewParserPCEPParser;
85 }
86
87 [literal]
88
89 augment "/config:modules/config:module/config:configuration" {
90         case pcep-parser-new-parser {
91                 when "/config:modules/config:module/config:type = 'pcep-parser-new-parser'";
92         }
93 }
94
95 Run mvn install on pcep-impl-config to generate Module and ModuleFactory files.
96 * Update Module to start your NewParserPCEPParserModule.java whent it's created
97
98 [literal]
99 @Override
100 public java.lang.AutoCloseable createInstance() {
101         return new InitiatedActivator();
102 }
103
104 ==== Writing an Extension to BGP +
105
106 Current standards support
107
108 Current bgp base-parser implementation supports following RFCs: +
109
110 http://tools.ietf.org/html/rfc4271[RFC4271] - A Border Gateway Protocol 4 (BGP-4) +
111 http://tools.ietf.org/html/rfc4724[RFC4724] - Graceful Restart Mechanism for BGP +
112 http://tools.ietf.org/html/rfc4760[RFC4760] - Multiprotocol Extensions for BGP-4 +
113 http://tools.ietf.org/html/rfc1997[RFC1997] - BGP Communities Attribute +
114 http://tools.ietf.org/html/rfc4360[RFC4360] - BGP Extended Communities Attribute +
115 http://tools.ietf.org/html/rfc6793[RFC6793] - BGP Support for Four-Octet Autonomous System (AS) Number Space (NEW speaker only) +
116
117 There is already one extension for: +
118 https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-06[draft-ietf-idr-ls-distribution] - in version 04 
119
120 === Implementing an Extension to BGP 
121
122 To implement an extension to BGP:
123
124 . Create a separate artefact (eclipse project) for your extension. 
125 Ensure it depends on pcep-api and pcep-spi.
126 . Write yang model for new elements or augment existing ones. 
127 . Perform `mvn install` to generate files from the model.
128 . Write parsers and serializers. All parsers need to implement *Parser* and *Serializer* interfaces from bgp-spi. For example: If you are writing a new capability, your parser should implement CapabilityParser and CapabilitySerializer).
129 Add Activator, that extends AbstractBGPExtensionProviderActivator, where you register your parsers and serializers. If your extension adds another AFI/SAFI you must to add another Activator that extends AbstractRIBExtensionProviderActivator and registrate new address family and subsequent address family.
130
131 === Updating Configuration
132 Update 31-bgp.xml. Register your parser as a module in bgp-impl: 
133
134 [literal]
135 <module>
136         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:new-parser">
137                 prefix:bgp-new-parser
138         </type>
139         <name>bgp-new-parser</name>
140 </module>
141
142 * Add it as an extension to bgp-parser-base:
143 [literal]
144 <extension>
145         <type xmlns:bgpspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi">
146                 bgpspi:extension
147         </type>
148         <name>bgp-new-parser</name>
149 </extension>
150
151 * Add the instance to services:
152 [literal]
153 <instance>
154         <name>bgp-new-parser</name>
155         <provider>/modules/module[type='bgp-new-parser'][name='bgp-new-parser']</provider>
156 </instance>
157
158 Also, if you are introducing new AFI/SAFI, do not forget to registrate your extension also to RIB.
159
160 * Create your own configuration file so that it generates Module and ModuleFactory classes for your new parser.
161
162 [literal]
163 identity bgp-new-parser {
164        base config:module-type;
165        config:provided-service bgpspi:extension;
166        config:provided-service ribspi:extension; // for new AFI/SAFI
167        config:java-name-prefix NewParser;
168 }
169
170 [literal]
171 augment "/config:modules/config:module/config:configuration" {
172        case bgp-new-parser {
173                when "/config:modules/config:module/config:type = 'bgp-new-parser'";
174        }
175 }
176
177 Run mvn install on your extension artefact to generate Module and ModuleFactory files.
178
179 * Update Module to start your NewParserModule.java whent it's created.
180 [literal]
181 @Override
182 public java.lang.AutoCloseable createInstance() {
183         return new NewParserActivator();
184 }
185
186
187 ==== Programmatic Interface(s)
188
189 Howto pull code from gerrit: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Pulling,_Hacking,_and_Pushing_the_Code_from_the_CLI[OpenDaylight Controller:Pulling, Hacking, and Pushing the Code from the CLI] +
190 Gerrit repository: https://git.opendaylight.org/gerrit/bgpcep[gerrit] +
191 Bugzilla: https://bugs.opendaylight.org/[Bugzilla] +
192 Mailing lists +
193
194 * bgpcep-bugs@opendaylight.org 
195 * bgpcep-dev@opendaylight.org 
196
197 YANG Models - https://jenkins.opendaylight.org/bgpcep/job/bgpcep-nightly/lastSuccessfulBuild/artifact/target/staging/releasepom/apidocs/index.html[BGP LS PCEP:Models] +
198
199 API Documentation â€“ https://wiki.opendaylight.org/view/BGP_LS_PCEP:Models[Javadoc API]
200
201 For debugging purposes, set lower log levels for bgpcep project in logback.xml.
202
203 [literal]
204 <logger name="org.opendaylight.protocol" level="TRACE" />
205 <logger name="org.opendaylight.bgpcep" level="TRACE" />
206
207
208 ==== Vendor Specific Constraints in PCEP
209 http://tools.ietf.org/html/draft-ietf-pce-rfc7150bis-00[draft-ietf-pce-rfc7150bis-00] - Conveying Vendor-Specific Constraints in the Path Computation Element communication Protocol.
210
211 Draft defines new PCEP object - Vendor Information object, that can be used to carry arbitrary, proprietary information such as vendor-specific constraints. Draft also defines new PCEP TLV - Vendor Information TLV that can be used to carry arbitrary information within any PCEP object that supports TLVs.
212
213 The ODL PCEP supports _draft-ietf-pce-rfc7150bis-00_ and provides abstraction for developers to create vendor-specific TLVs/objects extensions. The yang model of _vendor-information-tlv/object_ is defined in _pcep-types.yang_ and used in pcep objects/messages as defined in the draft.
214
215 This tutorial shows how to develop PCEP extension of vendor-information object and TLV for fictional company named My Vendor, whose enterprise number is 0. A result will be OSGi bundle and initial configuration xml file, that supports MY-VENDOR-TLV and MY-VENDOR-OBJECT in ODL.
216
217 * First, create simple maven module named _pcep-my-vendor_. For simplification assume the module parent is _pcep_ maven project. For bundle packaging add _plugin maven-bundle-plugin_ into _pom.xml_ and also _yang-maven-plugin_ for compile-time java code generating.
218
219 [literal]
220 <artifactId>pcep-my-vendor</artifactId>
221   <description>PCEP MY VENDOR EXTENSION</description>
222   <packaging>bundle</packaging>
223   <name>${project.artifactId}</name>
224   <build>
225     <plugins>
226       <plugin>
227         <groupId>org.apache.felix</groupId>
228         <artifactId>maven-bundle-plugin</artifactId>
229         <extensions>true</extensions>
230         <configuration>
231           <instructions>
232             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
233           </instructions>
234         </configuration>
235       </plugin>
236       <plugin>
237         <groupId>org.opendaylight.yangtools</groupId>
238         <artifactId>yang-maven-plugin</artifactId>
239       </plugin>
240     </plugins>
241   </build>
242   
243 * Add required dependencies into _pom.xml_.
244
245 [literal]
246  <dependencies>
247     <dependency>
248       <groupId>org.opendaylight.controller</groupId>
249       <artifactId>config-api</artifactId>
250     </dependency>
251     <dependency>
252       <groupId>${project.groupId}</groupId>
253       <artifactId>pcep-api</artifactId>
254     </dependency>
255     <dependency>
256       <groupId>${project.groupId}</groupId>
257       <artifactId>pcep-spi</artifactId>
258     </dependency>
259     <dependency>
260       <groupId>${project.groupId}</groupId>
261       <artifactId>pcep-impl</artifactId>
262     </dependency>
263   </dependencies>
264   
265 === Vendor Information TLV 
266
267 The Vendor Information TLV is used for vendor-specific information that applies to a specific PCEP object by including the TLV in the object. For the purpose of this tutorial, define MY-VENDOR-TLV, which can be loaded wih just simple unsigned 32-bit integer (4 bytes) as it's value and the TLV is carried in Open object.
268
269 *Yang model* +
270
271 * Initial step is to extend pcep-types and pcep-message yang models, augmentation target is _enterprise-specific-information_ (choice) located in Open messages's Open object. Create yang file (_pcep-my-vendor.yang_), in project's _src/main/yang_ folder, with definition of the vendor information and required augmentations.
272 * Now build project with maven, after that generated Java API's appears in _target/generated-sources/sal_.
273
274 [literal]
275 grouping my-vendor-information {
276     leaf payload {
277         type uint32;
278     }
279 }
280 augment "/msg:open/msg:open-message/msg:open/msg:tlvs/msg:vendor-information-tlv/msg:enterprise-specific-information" {
281     case my-vendor {
282         when "enterprise-number = 0";
283         uses my-vendor-information;
284     }
285 }
286
287 * Vendor Information TLV parser/serializer
288 * Next step is an implementation of the enterprise-specific-information (TLV's value) parser/serializer. It is simple serialization/deserialization of unsigned integer (long type in Java representation), other functionality is already presented in _org.opendaylight.protocol.pcep.impl.tlv.AbstractVendorInformationTlvParser abstract_ class. Create class extending _AbstractVendorInformationTlvParser_ and implement missing methods.
289
290 [literal]
291
292 public class MyVendorInformationTlvParser extends AbstractVendorInformationTlvParser {
293      private static final EnterpriseNumber EN = new EnterpriseNumber(0L);
294      @Override
295     public EnterpriseNumber getEnterpriseNumber() {
296         return EN;
297     }
298      @Override
299     public EnterpriseSpecificInformation parseEnterpriseSpecificInformation(final ByteBuf buffer)
300             throws PCEPDeserializerException {
301         return new MyVendorBuilder().setPayload(buffer.readUnsignedInt()).build();
302     }
303     @Override
304     public void serializeEnterpriseSpecificInformation(final EnterpriseSpecificInformation esi, final ByteBuf buffer) {
305         final MyVendor myVendorInfo = (MyVendor) esi;
306         buffer.writeInt(myVendorInfo.getPayload().intValue());
307     }
308 }
309
310 *Vendor Information TLV Activator* +
311
312 * Now, parser/serializer needs to be registered to _VendorInformationTlvRegistry_. Create class extending _AbstractPCEPExtensionProviderActivator_ and implement _startImpl_ method - register parser idenfied by enterprise number and register serializer identified by the class extending _EnterpriseSpecificInformation_.
313
314 [literal]
315
316 public class Activator extends AbstractPCEPExtensionProviderActivator {
317   @Override
318     protected List<AutoCloseable> startImpl(PCEPExtensionProviderContext context) {
319         final List<AutoCloseable> regs = new ArrayList<>();
320         final MyVendorInformationTlvParser parser = new MyVendorInformationTlvParser();
321         regs.add(context.registerVendorInformationTlvParser(parser.getEnterpriseNumber(), parser));
322         regs.add(context.registerVendorInformationTlvSerializer(MyVendor.class, parser));
323         return regs;
324     }
325  }
326
327 *Configuration Module* +
328
329 * Create configuration yang module with name i.e. _pcep-my-vendor-cfg.yang_. Define My Vendor parser extension service provider config module.
330 * Build project with maven to generate cofiguration module and module factory. They are located in _src/main/java_.
331 * Implement _MyVendorPCEPParserModule#createInstance()_ - return instance of Activator created above.
332
333 [literal]
334 identity pcep-parser-my-vendor {
335     base config:module-type;
336     config:provided-service spi:extension;
337     config:java-name-prefix MyVendorPCEPParser;
338 }
339 augment "/config:modules/config:module/config:configuration" {
340     case pcep-parser-my-vendor {
341         when "/config:modules/config:module/config:type = 'pcep-parser-my-vendor'";
342     }
343 }
344
345 [literal]
346 @Override
347     public java.lang.AutoCloseable createInstance() {
348         return new Activator();
349     }
350         
351 *Initial Configuration* +
352
353 Create initial configuration xml file, where module _pcep-parser-my-vendor_ is instantiated and injected into the _global-pcep-extensions_.
354
355 [literal]
356 <snapshot>
357     <required-capabilities>
358         <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:spi?module=odl-pcep-spi-cfg&amp;revision=2013-11-15</capability>
359        <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg?module=pcep-my-vendor-cfg&amp;revision=2014-09-20</capability>
360     </required-capabilities>
361     <configuration>
362         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
363             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
364                 <module>
365                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">prefix:pcep-extensions-impl</type>
366                     <name>global-pcep-extensions</name>
367                     <extension>
368                         <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
369                             pcepspi:extension
370                         </type>
371                         <name>pcep-parser-my-vendor</name>
372                     </extension>
373                 </module>
374                 <module>
375                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg">
376                         prefix:pcep-parser-my-vendor
377                     </type>
378                     <name>pcep-parser-my-vendor</name>
379                 </module>
380             </modules>
381             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
382                 <service>
383                     <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
384                         pcepspi:extension
385                     </type>
386                     <instance>
387                         <name>pcep-parser-my-vendor</name>
388                         <provider>/config/modules/module[name='pcep-parser-my-vendor']/instance[name='pcep-parser-my-vendor']</provider>
389                     </instance>
390                 </service>
391            </services>
392         </data>
393     </configuration>
394 </snapshot>
395
396
397 === Vendor Information Object 
398
399 For the tutorial purposes, define MY-VENDOR-OBJECT, which can be loaded with Ipv4 address (4 bytes) as it's value and the object is carried in PCRep message's response.
400
401 *Yang Model* +
402
403 * Initial step is to extend _pcep-types_ and _pcep-message_ yang models, augmentation target is _enterprise-specific-information_ (choice) located in PCRep messages. Create yang file (_pcep-my-vendor.yang_), in project _src/main/yang_ folder, with definition of the vendor information and required augmentations.
404 * Now build project with maven, after that generated Java API's appears in _target/generated-sources/sal_.
405
406 [literal]
407 grouping my-vendor-information {
408     leaf payload {
409         type inet:ipv4-address;
410     }
411 }
412  augment "/msg:pcrep/msg:pcrep-message/msg:replies/msg:vendor-information-object/msg:enterprise-specific-information" {
413     case my-vendor {
414         when "enterprise-number = 0";
415         uses my-vendor-information;
416     }
417 }
418
419 *Vendor Information Object Parser/Serializer* +
420
421 * Implementation of the _enterprise-sepecific-information_ (Object value) parser/serializer. It is simple serialization/deserialization of IPv4 address, other functionality is already presented in _org.opendaylight.protocol.pcep.impl.object.AbstractVendorInformationObjectParser_ abstract class. Create class extending _AbstractVendorInformationObjectParser_ and implement missing methods.
422
423 [literal]
424
425 public class MyVendorInformationObjectParser extends AbstractVendorInformationObjectParser {
426      private static final EnterpriseNumber EN = new EnterpriseNumber(0L);
427      @Override
428     public EnterpriseNumber getEnterpriseNumber() {
429         return EN;
430     }
431     @Override
432     public EnterpriseSpecificInformation parseEnterpriseSpecificInformation(final ByteBuf buffer)
433             throws PCEPDeserializerException {
434         return new MyVendorBuilder().setPayload(Ipv4Util.addressForByteBuf(buffer)).build();
435     }
436     @Override
437     public void serializeEnterpriseSpecificInformation(final EnterpriseSpecificInformation esi, final ByteBuf buffer) {
438         final MyVendor myVendor = (MyVendor) esi;
439         buffer.writeBytes(Ipv4Util.bytesForAddress(myVendor.getPayload()));
440     }
441 }
442
443 *Vendor Information Object Activator* +
444
445 Parser/serializer must be registered to VendorInformationObjectRegistry. Create class extending AbstractPCEPExtensionProviderActivator and implement startImpl method - register parser idenfied by enterprise number and register serializer identified by the class extending EnterpriseSpecificInformation.
446
447 [literal]
448 public class Activator extends AbstractPCEPExtensionProviderActivator {
449     @Override
450     protected List<AutoCloseable> startImpl(PCEPExtensionProviderContext context) {
451         final List<AutoCloseable> regs = new ArrayList<>();
452         final MyVendorInformationObjectParser parser = new MyVendorInformationObjectParser();
453         regs.add(context.registerVendorInformationObjectParser(parser.getEnterpriseNumber(), parser));
454         regs.add(context.registerVendorInformationObjectSerializer(MyVendor.class, parser));
455         return regs;
456     }
457  }
458
459 *Configuration Module* +
460
461 * Create configuration yang module with name (_pcep-my-vendor-cfg.yang_). 
462 * Define My Vendor parser extension service provider configuration module.
463 * Build project with maven to generate configuration module and module factory located in _src/main/java_.
464 * Implement _MyVendorPCEPParserModule#createInstance()_ - return instance of Activator created.
465
466 [literal]
467 identity pcep-parser-my-vendor {
468     base config:module-type;
469     config:provided-service spi:extension;
470     config:java-name-prefix MyVendorPCEPParser;
471 }
472  
473 augment "/config:modules/config:module/config:configuration" {
474     case pcep-parser-my-vendor {
475         when "/config:modules/config:module/config:type = 'pcep-parser-my-vendor'";
476     }
477 }
478
479 [literal]
480     @Override
481     public java.lang.AutoCloseable createInstance() {
482         return new Activator();
483     }
484
485
486 *Initial Configuration* +
487
488 Create initial configuration xml file, where module _pcep-parser-my-vendor_ is instantiated and injected into the _global-pcep-extensions_.
489
490 [literal]
491 <snapshot>
492     <required-capabilities>
493         <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:spi?module=odl-pcep-spi-cfg&amp;revision=2013-11-15</capability>
494        <capability>urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg?module=pcep-my-vendor-cfg&amp;revision=2014-09-20</capability>
495     </required-capabilities>
496     <configuration>
497         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
498             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
499                 <module>
500                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
501                         prefix:pcep-extensions-impl
502                     </type>
503                     <name>global-pcep-extensions</name>
504                     <extension>
505                         <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
506                             pcepspi:extension
507                         </type>
508                         <name>pcep-parser-my-vendor</name>
509                     </extension>
510                 </module>
511                 <module>
512                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:pcep:my:vendor:cfg">
513                         prefix:pcep-parser-my-vendor
514                     </type>
515                     <name>pcep-parser-my-vendor</name>
516                 </module>
517             </modules>
518             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
519                 <service>
520                     <type xmlns:pcepspi="urn:opendaylight:params:xml:ns:yang:controller:pcep:spi">
521                         pcepspi:extension
522                     </type>
523                     <instance>
524                         <name>pcep-parser-my-vendor</name>
525                         <provider>/config/modules/module[name='pcep-parser-my-vendor']/instance[name='pcep-parser-my-vendor']</provider>
526                     </instance>
527                 </service>
528            </services>
529         </data>
530     </configuration>
531 </snapshot>