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