Move integration tests to mdsal-it-parent
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / serializer / MapNotifySerializer.java
1 /*
2  * Copyright (c) 2014 Contextream, 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.lispflowmapping.implementation.serializer;
9
10 import java.nio.ByteBuffer;
11 import java.util.ArrayList;
12
13 import org.opendaylight.lispflowmapping.implementation.lisp.exception.LispSerializationException;
14 import org.opendaylight.lispflowmapping.implementation.util.ByteUtil;
15 import org.opendaylight.lispflowmapping.implementation.util.NumberUtil;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapNotify;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecordBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapnotifymessage.MapNotifyBuilder;
20
21 /**
22  * This class deals with serializing map notify from the java object to udp.
23  */
24 public class MapNotifySerializer {
25
26     private static final MapNotifySerializer INSTANCE = new MapNotifySerializer();
27
28     // Private constructor prevents instantiation from other classes
29     private MapNotifySerializer() {
30     }
31
32     public static MapNotifySerializer getInstance() {
33         return INSTANCE;
34     }
35
36     public ByteBuffer serialize(MapNotify mapNotify) {
37         int size = Length.HEADER_SIZE;
38         if (mapNotify.getAuthenticationData() != null) {
39             size += mapNotify.getAuthenticationData().length;
40         }
41         if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
42             size += org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer.Length.XTRID_SIZE +
43                     org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer.Length.SITEID_SIZE;
44         }
45         for (EidToLocatorRecord eidToLocatorRecord : mapNotify.getEidToLocatorRecord()) {
46             size += EidToLocatorRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord);
47         }
48
49         ByteBuffer replyBuffer = ByteBuffer.allocate(size);
50         replyBuffer.put((byte) (LispMessageEnum.MapNotify.getValue() << 4));
51         replyBuffer.position(replyBuffer.position() + Length.RES);
52         if (mapNotify.getEidToLocatorRecord() != null) {
53             replyBuffer.put((byte) mapNotify.getEidToLocatorRecord().size());
54         } else {
55             replyBuffer.put((byte) 0);
56         }
57         replyBuffer.putLong(NumberUtil.asLong(mapNotify.getNonce()));
58         replyBuffer.putShort(NumberUtil.asShort(mapNotify.getKeyId()));
59         if (mapNotify.getAuthenticationData() != null) {
60             replyBuffer.putShort((short) mapNotify.getAuthenticationData().length);
61             replyBuffer.put(mapNotify.getAuthenticationData());
62         } else {
63             replyBuffer.putShort((short) 0);
64         }
65
66         if (mapNotify.getEidToLocatorRecord() != null) {
67             for (EidToLocatorRecord eidToLocatorRecord : mapNotify.getEidToLocatorRecord()) {
68                 EidToLocatorRecordSerializer.getInstance().serialize(replyBuffer, eidToLocatorRecord);
69             }
70         }
71
72         if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
73             replyBuffer.put(mapNotify.getXtrId());
74             replyBuffer.put(mapNotify.getSiteId());
75         }
76         replyBuffer.clear();
77         return replyBuffer;
78     }
79
80     public MapNotify deserialize(ByteBuffer notifyBuffer) {
81         try {
82             MapNotifyBuilder builder = new MapNotifyBuilder();
83
84             byte typeAndFlags = notifyBuffer.get();
85             boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
86             builder.setXtrSiteIdPresent(xtrSiteIdPresent);
87
88             notifyBuffer.position(notifyBuffer.position() + Length.RES);
89
90             byte recordCount = (byte) ByteUtil.getUnsignedByte(notifyBuffer);
91             builder.setNonce(notifyBuffer.getLong());
92             builder.setKeyId(notifyBuffer.getShort());
93             short authenticationLength = notifyBuffer.getShort();
94             byte[] authenticationData = new byte[authenticationLength];
95             notifyBuffer.get(authenticationData);
96             builder.setAuthenticationData(authenticationData);
97
98             builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
99             for (int i = 0; i < recordCount; i++) {
100                 builder.getEidToLocatorRecord().add(
101                         new EidToLocatorRecordBuilder(EidToLocatorRecordSerializer.getInstance().deserialize(notifyBuffer)).build());
102             }
103
104             if (xtrSiteIdPresent) {
105                 byte[] xtrId  = new byte[org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer.Length.XTRID_SIZE];
106                 notifyBuffer.get(xtrId);
107                 byte[] siteId = new byte[org.opendaylight.lispflowmapping.implementation.serializer.MapRegisterSerializer.Length.SITEID_SIZE];
108                 notifyBuffer.get(siteId);
109                 builder.setXtrId(xtrId);
110                 builder.setSiteId(siteId);
111             }
112             notifyBuffer.limit(notifyBuffer.position());
113             return builder.build();
114         } catch (RuntimeException re) {
115             throw new LispSerializationException("Couldn't deserialize Map-Notify (len=" + notifyBuffer.capacity() + ")", re);
116         }
117     }
118
119     private interface Flags {
120         byte XTRSITEID = 0x08;
121     }
122
123     private interface Length {
124         int HEADER_SIZE = 16;
125         int RES = 2;
126     }
127
128 }