Checkstyle: fix issues and enforce on lisp-proto
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / MapRegisterSerializer.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.net.Inet4Address;
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.nio.ByteBuffer;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.apache.commons.lang3.BooleanUtils;
17 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
18 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
19 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv6AddressBinary;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
31
32 /**
33  * This class deals with deserializing map register from udp to the java object.
34  */
35 public final class MapRegisterSerializer {
36
37     private static final MapRegisterSerializer INSTANCE = new MapRegisterSerializer();
38
39     // Private constructor prevents instantiation from other classes
40     private MapRegisterSerializer() {
41     }
42
43     public static MapRegisterSerializer getInstance() {
44         return INSTANCE;
45     }
46
47     public ByteBuffer serialize(MapRegister mapRegister) {
48         int size = Length.HEADER_SIZE;
49         if (mapRegister.getAuthenticationData() != null) {
50             size += mapRegister.getAuthenticationData().length;
51         }
52         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
53             size += Length.XTRID_SIZE + Length.SITEID_SIZE;
54         }
55         for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
56             size += MappingRecordSerializer.getInstance().getSerializationSize(eidToLocatorRecord.getMappingRecord());
57         }
58
59         ByteBuffer registerBuffer = ByteBuffer.allocate(size);
60         registerBuffer.put((byte) ((byte) (MessageType.MapRegister.getIntValue() << 4)
61                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isProxyMapReply()), Flags.PROXY)
62                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isXtrSiteIdPresent()), Flags.XTRSITEID)));
63         registerBuffer.position(registerBuffer.position() + Length.RES);
64         registerBuffer.put((byte)
65                 (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isMergeEnabled()), Flags.MERGE_ENABLED)
66                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRegister.isWantMapNotify()), Flags.WANT_MAP_NOTIFY)));
67         registerBuffer.put((byte) mapRegister.getMappingRecordItem().size());
68         registerBuffer.putLong(NumberUtil.asLong(mapRegister.getNonce()));
69         registerBuffer.putShort(NumberUtil.asShort(mapRegister.getKeyId()));
70
71         if (mapRegister.getAuthenticationData() != null) {
72             registerBuffer.putShort((short) mapRegister.getAuthenticationData().length);
73             registerBuffer.put(mapRegister.getAuthenticationData());
74         } else {
75             registerBuffer.putShort((short) 0);
76         }
77         for (MappingRecordItem eidToLocatorRecord : mapRegister.getMappingRecordItem()) {
78             MappingRecordSerializer.getInstance().serialize(registerBuffer, eidToLocatorRecord.getMappingRecord());
79         }
80
81         if (mapRegister.isXtrSiteIdPresent() != null && mapRegister.isXtrSiteIdPresent()) {
82             registerBuffer.put(mapRegister.getXtrId().getValue());
83             registerBuffer.put(mapRegister.getSiteId().getValue());
84         }
85         registerBuffer.clear();
86         return registerBuffer;
87     }
88
89     @SuppressWarnings("checkstyle:IllegalCatch")
90     public MapRegister deserialize(ByteBuffer registerBuffer, InetAddress sourceRloc) {
91         try {
92             MapRegisterBuilder builder = new MapRegisterBuilder();
93             builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
94
95             byte typeAndFlags = registerBuffer.get();
96             boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
97             builder.setProxyMapReply(ByteUtil.extractBit(typeAndFlags, Flags.PROXY));
98             builder.setXtrSiteIdPresent(xtrSiteIdPresent);
99
100             registerBuffer.position(registerBuffer.position() + Length.RES);
101             byte mergeAndMapReply = registerBuffer.get();
102             builder.setWantMapNotify(ByteUtil.extractBit(mergeAndMapReply, Flags.WANT_MAP_NOTIFY));
103             builder.setMergeEnabled(ByteUtil.extractBit(mergeAndMapReply, Flags.MERGE_ENABLED));
104             byte recordCount = (byte) ByteUtil.getUnsignedByte(registerBuffer);
105             builder.setNonce(registerBuffer.getLong());
106             builder.setKeyId(registerBuffer.getShort());
107             short authenticationLength = registerBuffer.getShort();
108             byte[] authenticationData = new byte[authenticationLength];
109             registerBuffer.get(authenticationData);
110             builder.setAuthenticationData(authenticationData);
111
112             if (xtrSiteIdPresent) {
113                 List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
114                 for (int i = 0; i < recordCount; i++) {
115                     mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(registerBuffer));
116                 }
117                 byte[] xtrIdBuf  = new byte[Length.XTRID_SIZE];
118                 registerBuffer.get(xtrIdBuf);
119                 XtrId xtrId = new XtrId(xtrIdBuf);
120                 byte[] siteIdBuf = new byte[Length.SITEID_SIZE];
121                 registerBuffer.get(siteIdBuf);
122                 SiteId siteId = new SiteId(siteIdBuf);
123                 builder.setXtrId(xtrId);
124                 builder.setSiteId(siteId);
125                 for (MappingRecordBuilder mrb : mrbs) {
126                     mrb.setXtrId(xtrId);
127                     mrb.setSiteId(siteId);
128                     mrb.setSourceRloc(getSourceRloc(sourceRloc));
129                     builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
130                             mrb.build()).build());
131                 }
132             } else {
133                 for (int i = 0; i < recordCount; i++) {
134                     builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
135                             MappingRecordSerializer.getInstance().deserialize(registerBuffer)).build());
136                 }
137             }
138
139             registerBuffer.limit(registerBuffer.position());
140             byte[] mapRegisterBytes = new byte[registerBuffer.position()];
141             registerBuffer.position(0);
142             registerBuffer.get(mapRegisterBytes);
143             return builder.build();
144         } catch (RuntimeException re) {
145             throw new LispSerializationException("Couldn't deserialize Map-Register (len="
146                     + registerBuffer.capacity() + ")", re);
147         }
148
149     }
150
151     private static IpAddressBinary getSourceRloc(InetAddress sourceRloc) {
152         if (sourceRloc == null) {
153             sourceRloc = Inet4Address.getLoopbackAddress();
154         }
155
156         if (sourceRloc instanceof Inet4Address) {
157             return new IpAddressBinary(new Ipv4AddressBinary(sourceRloc.getAddress()));
158         } else if (sourceRloc instanceof Inet6Address) {
159             return new IpAddressBinary(new Ipv6AddressBinary(sourceRloc.getAddress()));
160         }
161
162         return null;
163     }
164
165     private interface Flags {
166         byte PROXY = 0x08;
167         byte XTRSITEID = 0x02;
168         byte MERGE_ENABLED = 0x04;
169         byte WANT_MAP_NOTIFY = 0x01;
170     }
171
172     public interface Length {
173         int HEADER_SIZE = 16;
174         int XTRID_SIZE = 16;
175         int SITEID_SIZE = 8;
176         int RES = 1;
177     }
178 }