/*
* Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.openflowplugin.impl.protocol.deserialization.messages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
import org.opendaylight.openflowplugin.impl.protocol.deserialization.util.ActionUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupMessageBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModCommand;
import io.netty.buffer.ByteBuf;
public class GroupMessageDeserializer implements OFDeserializer<GroupMessage>, DeserializerRegistryInjector {
private static final byte PADDING = 1;
private static final byte PADDING_IN_BUCKETS_HEADER = 4;
private static final byte BUCKETS_HEADER_LENGTH = 16;
private static final Comparator<Bucket> COMPARATOR = (bucket1, bucket2) -> {
if (bucket1.getBucketId() == null || bucket2.getBucketId() == null) return 0;
return bucket1.getBucketId().getValue().compareTo(bucket2.getBucketId().getValue());
};
private DeserializerRegistry registry;
@Override
public GroupMessage deserialize(ByteBuf message) {
final GroupMessageBuilder builder = new GroupMessageBuilder()
.setVersion((short) EncodeConstants.OF13_VERSION_ID)
.setXid(message.readUnsignedInt())
.setCommand(GroupModCommand.forValue(message.readUnsignedShort()));
builder.setGroupType(GroupTypes.forValue(message.readUnsignedByte()));
message.skipBytes(PADDING);
builder.setGroupId(new GroupId(message.readUnsignedInt()));
final List<Bucket> buckets = new ArrayList<>();
while (message.readableBytes() > 0) {
final int length = message.readUnsignedShort();
final BucketBuilder bucket = new BucketBuilder()
.setWeight(message.readUnsignedShort())
.setWatchPort(message.readUnsignedInt())
.setWatchGroup(message.readUnsignedInt());
message.skipBytes(PADDING_IN_BUCKETS_HEADER);
if (message.readableBytes() > 0) {
final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list
.Action> actions = new ArrayList<>();
final int startIndex = message.readerIndex();
final int bucketLength = length - BUCKETS_HEADER_LENGTH;
int offset = 0;
while ((message.readerIndex() - startIndex) < bucketLength) {
actions.add(new ActionBuilder()
.setKey(new ActionKey(offset))
.setOrder(offset)
.setAction(ActionUtil.readAction(EncodeConstants.OF13_VERSION_ID, message, registry,
ActionPath.GROUPDESCSTATSUPDATED_GROUPDESCSTATS_BUCKETS_BUCKET_ACTION))
.build());
offset++;
}
bucket.setAction(actions);
}
buckets.add(bucket.build());
}
Collections.sort(buckets, COMPARATOR);
return builder
.setBuckets(new BucketsBuilder()
.setBucket(buckets)
.build())
.build();
}
@Override
public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
registry = deserializerRegistry;
}
}