2 * Copyright (c) 2014 Contextream, Inc. and others. All rights reserved.
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
8 package org.opendaylight.lispflowmapping.lisp.serializer;
10 import java.nio.ByteBuffer;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.apache.commons.lang3.BooleanUtils;
14 import org.opendaylight.lispflowmapping.lisp.serializer.exception.LispSerializationException;
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.lisp.proto.rev151105.MapNotify;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
27 * This class deals with serializing map notify from the java object to udp.
29 public final class MapNotifySerializer {
31 private static final MapNotifySerializer INSTANCE = new MapNotifySerializer();
33 // Private constructor prevents instantiation from other classes
34 private MapNotifySerializer() {
37 public static MapNotifySerializer getInstance() {
41 public ByteBuffer serialize(MapNotify mapNotify) {
42 int size = Length.HEADER_SIZE;
43 if (mapNotify.getAuthenticationData() != null) {
44 size += mapNotify.getAuthenticationData().length;
46 if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
47 size += org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.XTRID_SIZE
48 + org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer.Length.SITEID_SIZE;
50 for (MappingRecordItem mappingRecord : mapNotify.getMappingRecordItem()) {
51 size += MappingRecordSerializer.getInstance().getSerializationSize(mappingRecord.getMappingRecord());
54 ByteBuffer replyBuffer = ByteBuffer.allocate(size);
55 replyBuffer.put((byte) ((byte) (MessageType.MapNotify.getIntValue() << 4)
56 | ByteUtil.boolToBit(BooleanUtils.isTrue(mapNotify.isXtrSiteIdPresent()), Flags.XTRSITEID)));
57 replyBuffer.position(replyBuffer.position() + Length.RES);
58 replyBuffer.put(ByteUtil.boolToBit(BooleanUtils.isTrue(mapNotify.isMergeEnabled()), Flags.MERGE_ENABLED));
59 if (mapNotify.getMappingRecordItem() != null) {
60 replyBuffer.put((byte) mapNotify.getMappingRecordItem().size());
62 replyBuffer.put((byte) 0);
64 replyBuffer.putLong(NumberUtil.asLong(mapNotify.getNonce()));
65 replyBuffer.putShort(NumberUtil.asShort(mapNotify.getKeyId()));
66 if (mapNotify.getAuthenticationData() != null) {
67 replyBuffer.putShort((short) mapNotify.getAuthenticationData().length);
68 replyBuffer.put(mapNotify.getAuthenticationData());
70 replyBuffer.putShort((short) 0);
73 if (mapNotify.getMappingRecordItem() != null) {
74 for (MappingRecordItem mappingRecord : mapNotify.getMappingRecordItem()) {
75 MappingRecordSerializer.getInstance().serialize(replyBuffer, mappingRecord.getMappingRecord());
79 if (mapNotify.isXtrSiteIdPresent() != null && mapNotify.isXtrSiteIdPresent()) {
80 replyBuffer.put(mapNotify.getXtrId().getValue());
81 replyBuffer.put(mapNotify.getSiteId().getValue());
87 @SuppressWarnings("checkstyle:IllegalCatch")
88 public MapNotify deserialize(ByteBuffer notifyBuffer) {
90 MapNotifyBuilder builder = new MapNotifyBuilder();
91 builder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
93 byte typeAndFlags = notifyBuffer.get();
94 boolean xtrSiteIdPresent = ByteUtil.extractBit(typeAndFlags, Flags.XTRSITEID);
95 builder.setXtrSiteIdPresent(xtrSiteIdPresent);
97 notifyBuffer.position(notifyBuffer.position() + Length.RES);
98 builder.setMergeEnabled(ByteUtil.extractBit(notifyBuffer.get(), Flags.MERGE_ENABLED));
100 byte recordCount = (byte) ByteUtil.getUnsignedByte(notifyBuffer);
101 builder.setNonce(notifyBuffer.getLong());
102 builder.setKeyId(notifyBuffer.getShort());
103 short authenticationLength = notifyBuffer.getShort();
104 byte[] authenticationData = new byte[authenticationLength];
105 notifyBuffer.get(authenticationData);
106 builder.setAuthenticationData(authenticationData);
108 if (xtrSiteIdPresent) {
109 List<MappingRecordBuilder> mrbs = new ArrayList<MappingRecordBuilder>();
110 for (int i = 0; i < recordCount; i++) {
111 mrbs.add(MappingRecordSerializer.getInstance().deserializeToBuilder(notifyBuffer));
113 byte[] xtrIdBuf = new byte[MapRegisterSerializer.Length.XTRID_SIZE];
114 notifyBuffer.get(xtrIdBuf);
115 XtrId xtrId = new XtrId(xtrIdBuf);
116 byte[] siteIdBuf = new byte[MapRegisterSerializer.Length.SITEID_SIZE];
117 notifyBuffer.get(siteIdBuf);
118 SiteId siteId = new SiteId(siteIdBuf);
119 builder.setXtrId(xtrId);
120 builder.setSiteId(siteId);
121 for (MappingRecordBuilder mrb : mrbs) {
123 mrb.setSiteId(siteId);
124 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
125 mrb.build()).build());
128 for (int i = 0; i < recordCount; i++) {
129 builder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
130 MappingRecordSerializer.getInstance().deserialize(notifyBuffer)).build());
134 notifyBuffer.limit(notifyBuffer.position());
135 return builder.build();
136 } catch (RuntimeException re) {
137 throw new LispSerializationException("Couldn't deserialize Map-Notify (len="
138 + notifyBuffer.capacity() + ")", re);
142 private interface Flags {
143 byte XTRSITEID = 0x08;
144 byte MERGE_ENABLED = 0x04;
147 private interface Length {
148 int HEADER_SIZE = 16;