Checkstyle: fix issues and enforce on lisp-proto
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / serializer / MapRequestSerializer.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 import org.apache.commons.lang3.BooleanUtils;
13 import org.opendaylight.lispflowmapping.lisp.serializer.address.LispAddressSerializer;
14 import org.opendaylight.lispflowmapping.lisp.serializer.address.LispAddressSerializerContext;
15 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
16 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
17 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
18 import org.opendaylight.lispflowmapping.lisp.util.NumberUtil;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRloc;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRlocBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * This class deals with deserializing map request from udp to the java object.
32  */
33 public final class MapRequestSerializer {
34
35     private static final MapRequestSerializer INSTANCE = new MapRequestSerializer();
36     protected static final Logger LOG = LoggerFactory.getLogger(MapRequestSerializer.class);
37
38     // Private constructor prevents instantiation from other classes
39     private MapRequestSerializer() {
40     }
41
42     public static MapRequestSerializer getInstance() {
43         return INSTANCE;
44     }
45
46     public ByteBuffer serialize(MapRequest mapRequest) {
47         int size = Length.HEADER_SIZE;
48         if (mapRequest.getSourceEid() != null && mapRequest.getSourceEid().getEid() != null) {
49             size += LispAddressSerializer.getInstance().getAddressSize(mapRequest.getSourceEid().getEid());
50         } else {
51             size += 2;
52         }
53         if (mapRequest.getItrRloc() != null) {
54             for (ItrRloc address : mapRequest.getItrRloc()) {
55                 size += LispAddressSerializer.getInstance().getAddressSize(address.getRloc());
56             }
57         }
58         if (mapRequest.getEidItem() != null) {
59             for (EidItem record : mapRequest.getEidItem()) {
60                 size += 2 + LispAddressSerializer.getInstance().getAddressSize(record.getEid());
61             }
62         }
63         ByteBuffer requestBuffer = ByteBuffer.allocate(size);
64         requestBuffer.put((byte) ((byte) (MessageType.MapRequest.getIntValue() << 4)
65                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isAuthoritative()), Flags.AUTHORITATIVE)
66                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isMapDataPresent()), Flags.MAP_DATA_PRESENT)
67                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isProbe()), Flags.PROBE) | ByteUtil.boolToBit(
68                 BooleanUtils.isTrue(mapRequest.isSmr()), Flags.SMR)));
69         requestBuffer.put((byte) (ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isPitr()), Flags.PITR)
70                 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapRequest.isSmrInvoked()), Flags.SMR_INVOKED)));
71         if (mapRequest.getItrRloc() != null) {
72             int irc = mapRequest.getItrRloc().size();
73             if (irc > 0) {
74                 irc--;
75             }
76             requestBuffer.put((byte) (irc));
77         } else {
78             requestBuffer.put((byte) 0);
79
80         }
81         if (mapRequest.getEidItem() != null) {
82             requestBuffer.put((byte) mapRequest.getEidItem().size());
83         } else {
84             requestBuffer.put((byte) 0);
85
86         }
87         requestBuffer.putLong(NumberUtil.asLong(mapRequest.getNonce()));
88         if (mapRequest.getSourceEid() != null && mapRequest.getSourceEid().getEid() != null) {
89             LispAddressSerializer.getInstance().serialize(requestBuffer, mapRequest.getSourceEid().getEid());
90         } else {
91             requestBuffer.putShort((short) 0);
92         }
93         if (mapRequest.getItrRloc() != null) {
94             for (ItrRloc address : mapRequest.getItrRloc()) {
95                 LispAddressSerializer.getInstance().serialize(requestBuffer, address.getRloc());
96             }
97         }
98         if (mapRequest.getEidItem() != null) {
99             for (EidItem record : mapRequest.getEidItem()) {
100                 requestBuffer.put((byte) 0);
101                 requestBuffer.put((byte) MaskUtil.getMaskForAddress(record.getEid().getAddress()));
102                 LispAddressSerializer.getInstance().serialize(requestBuffer, record.getEid());
103             }
104         }
105         if (mapRequest.getMapReply() != null) {
106             ByteBuffer replyBuffer = ByteBuffer.allocate(MappingRecordSerializer.getInstance()
107                     .getSerializationSize(mapRequest.getMapReply().getMappingRecord()));
108             MappingRecordSerializer.getInstance().serialize(replyBuffer, mapRequest.getMapReply().getMappingRecord());
109             ByteBuffer combinedBuffer = ByteBuffer.allocate(requestBuffer.capacity() + replyBuffer.capacity());
110             combinedBuffer.put(requestBuffer.array());
111             combinedBuffer.put(replyBuffer.array());
112             return combinedBuffer;
113         }
114         return requestBuffer;
115     }
116
117     @SuppressWarnings("checkstyle:IllegalCatch")
118     public MapRequest deserialize(ByteBuffer requestBuffer) {
119         try {
120             MapRequestBuilder builder = new MapRequestBuilder();
121
122             final byte typeAndFlags = requestBuffer.get();
123             builder.setAuthoritative(ByteUtil.extractBit(typeAndFlags, Flags.AUTHORITATIVE));
124             builder.setMapDataPresent(ByteUtil.extractBit(typeAndFlags, Flags.MAP_DATA_PRESENT));
125             builder.setProbe(ByteUtil.extractBit(typeAndFlags, Flags.PROBE));
126             builder.setSmr(ByteUtil.extractBit(typeAndFlags, Flags.SMR));
127
128             final byte moreFlags = requestBuffer.get();
129             builder.setPitr(ByteUtil.extractBit(moreFlags, Flags.PITR));
130             builder.setSmrInvoked(ByteUtil.extractBit(moreFlags, Flags.SMR_INVOKED));
131
132             final int itrCount = ByteUtil.getUnsignedByte(requestBuffer) + 1;
133             final int recordCount = ByteUtil.getUnsignedByte(requestBuffer);
134             builder.setNonce(requestBuffer.getLong());
135             LispAddressSerializerContext ctx = new LispAddressSerializerContext(
136                     LispAddressSerializerContext.MASK_LEN_MISSING);
137             builder.setSourceEid(new SourceEidBuilder().setEid(
138                     LispAddressSerializer.getInstance().deserializeEid(requestBuffer, ctx)).build());
139
140             if (builder.getItrRloc() == null) {
141                 builder.setItrRloc(new ArrayList<ItrRloc>());
142             }
143             for (int i = 0; i < itrCount; i++) {
144                 builder.getItrRloc().add(new ItrRlocBuilder().setRloc(
145                         LispAddressSerializer.getInstance().deserializeRloc(requestBuffer)).build());
146             }
147
148             if (builder.getEidItem() == null) {
149                 builder.setEidItem(new ArrayList<EidItem>());
150             }
151             for (int i = 0; i < recordCount; i++) {
152                 builder.getEidItem().add(new EidItemBuilder().setEid(
153                         EidRecordSerializer.getInstance().deserialize(requestBuffer)).build());
154             }
155             if (builder.isMapDataPresent() && requestBuffer.hasRemaining()) {
156                 try {
157                     builder.setMapReply(new org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
158                             .maprequest.MapReplyBuilder().setMappingRecord(
159                             MappingRecordSerializer.getInstance().deserialize(requestBuffer)).build()).build();
160                 } catch (RuntimeException re) {
161                     LOG.warn("Couldn't deserialize Map-Reply encapsulated in Map-Request", re);
162                 }
163             }
164             return builder.build();
165         } catch (RuntimeException re) {
166             throw new LispSerializationException("Couldn't deserialize Map-Request (len="
167                     + requestBuffer.capacity() + ")", re);
168         }
169     }
170
171     public interface Flags {
172         byte AUTHORITATIVE = 0x08;
173         byte MAP_DATA_PRESENT = 0x04;
174         byte PROBE = 0x02;
175         byte SMR = 0x01;
176
177         byte PITR = (byte) 0x80;
178         byte SMR_INVOKED = 0x40;
179     }
180
181     private interface Length {
182         int HEADER_SIZE = 12;
183     }
184
185 }