use of org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase in project openflowplugin by opendaylight.
the class ActionConvertorV13Test method testToMDSalActions2.
/**
* Test {@link ActionConvertor#convert(List, ActionConvertorData)}}.
*/
// @Test
public void testToMDSalActions2() {
OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder();
OutputActionBuilder outputBuilder = new OutputActionBuilder();
outputBuilder.setPort(new PortNumber(42L));
outputBuilder.setMaxLength(52);
caseBuilder.setOutputAction(outputBuilder.build());
ActionBuilder actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(caseBuilder.build());
List<Action> actions = new ArrayList<>();
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new CopyTtlOutCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new CopyTtlInCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
SetMplsTtlCaseBuilder setMplsTtlCaseBuilder = new SetMplsTtlCaseBuilder();
SetMplsTtlActionBuilder setMplsTtlBuilder = new SetMplsTtlActionBuilder();
setMplsTtlBuilder.setMplsTtl((short) 4);
setMplsTtlCaseBuilder.setSetMplsTtlAction(setMplsTtlBuilder.build());
actionBuilder.setActionChoice(setMplsTtlCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new DecMplsTtlCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
PushVlanCaseBuilder pushVlanCaseBuilder = new PushVlanCaseBuilder();
PushVlanActionBuilder pushVlanBuilder = new PushVlanActionBuilder();
pushVlanBuilder.setEthertype(new EtherType(new EtherType(16)));
pushVlanCaseBuilder.setPushVlanAction(pushVlanBuilder.build());
actionBuilder.setActionChoice(pushVlanCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new PopVlanCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
PushMplsCaseBuilder pushMplsCaseBuilder = new PushMplsCaseBuilder();
PushMplsActionBuilder pushMplsBuilder = new PushMplsActionBuilder();
pushMplsBuilder.setEthertype(new EtherType(new EtherType(17)));
pushMplsCaseBuilder.setPushMplsAction(pushMplsBuilder.build());
actionBuilder.setActionChoice(pushMplsCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
PopMplsCaseBuilder popMplsCaseBuilder = new PopMplsCaseBuilder();
PopMplsActionBuilder popMplsBuilder = new PopMplsActionBuilder();
popMplsBuilder.setEthertype(new EtherType(new EtherType(18)));
popMplsCaseBuilder.setPopMplsAction(popMplsBuilder.build());
actionBuilder.setActionChoice(popMplsCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
SetQueueCaseBuilder setQueueCaseBuilder = new SetQueueCaseBuilder();
SetQueueActionBuilder setQueueBuilder = new SetQueueActionBuilder();
setQueueBuilder.setQueueId(1234L);
setQueueCaseBuilder.setSetQueueAction(setQueueBuilder.build());
actionBuilder.setActionChoice(setQueueCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
GroupCaseBuilder groupCaseBuilder = new GroupCaseBuilder();
GroupActionBuilder groupActionBuilder = new GroupActionBuilder();
groupActionBuilder.setGroupId(555L);
groupCaseBuilder.setGroupAction(groupActionBuilder.build());
actionBuilder.setActionChoice(groupCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
SetNwTtlCaseBuilder nwTtlCaseBuilder = new SetNwTtlCaseBuilder();
SetNwTtlActionBuilder nwTtlBuilder = new SetNwTtlActionBuilder();
nwTtlBuilder.setNwTtl((short) 8);
nwTtlCaseBuilder.setSetNwTtlAction(nwTtlBuilder.build());
actionBuilder.setActionChoice(nwTtlCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new DecNwTtlCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
MatchEntryBuilder matchBuilder = new MatchEntryBuilder();
matchBuilder.setOxmClass(OpenflowBasicClass.class);
matchBuilder.setOxmMatchField(InPort.class);
matchBuilder.setHasMask(false);
InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder();
InPortBuilder inPortBuilder = new InPortBuilder();
inPortBuilder.setPortNumber(new PortNumber(1L));
inPortCaseBuilder.setInPort(inPortBuilder.build());
matchBuilder.setMatchEntryValue(inPortCaseBuilder.build());
List<MatchEntry> entries = new ArrayList<>();
entries.add(matchBuilder.build());
SetFieldActionBuilder setFieldBuilder = new SetFieldActionBuilder();
setFieldBuilder.setMatchEntry(entries);
SetFieldCaseBuilder setFieldCaseBuilder = new SetFieldCaseBuilder();
setFieldCaseBuilder.setSetFieldAction(setFieldBuilder.build());
actionBuilder.setActionChoice(setFieldCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
PushPbbCaseBuilder pushPbbCaseBuilder = new PushPbbCaseBuilder();
PushPbbActionBuilder pushPbbBuilder = new PushPbbActionBuilder();
pushPbbBuilder.setEthertype(new EtherType(new EtherType(19)));
pushPbbCaseBuilder.setPushPbbAction(pushPbbBuilder.build());
actionBuilder.setActionChoice(pushPbbCaseBuilder.build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new PopPbbCaseBuilder().build());
actions.add(actionBuilder.build());
// Add some unsupported actions and check if they are missing from results
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new SetNwDstCaseBuilder().build());
actions.add(actionBuilder.build());
actionBuilder = new ActionBuilder();
actionBuilder.setActionChoice(new StripVlanCaseBuilder().build());
actions.add(actionBuilder.build());
ActionResponseConvertorData data = new ActionResponseConvertorData(OFConstants.OFP_VERSION_1_3);
data.setActionPath(ActionPath.FLOWS_STATISTICS_UPDATE_APPLY_ACTIONS);
Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action>> mdSalActionsOptional = convertorManager.convert(actions, data);
List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action> mdSalActions = mdSalActionsOptional.orElse(Collections.emptyList());
Assert.assertEquals("Wrong number of output actions", 16, mdSalActions.size());
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = mdSalActions.get(0);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.OutputActionCase", action.getImplementedInterface().getName());
OutputActionCase output = (OutputActionCase) action;
Assert.assertEquals("Wrong output port", "42", output.getOutputAction().getOutputNodeConnector().getValue());
Assert.assertEquals("Wrong max length", 52, output.getOutputAction().getMaxLength().intValue());
action = mdSalActions.get(1);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.CopyTtlOutCase", action.getImplementedInterface().getName());
action = mdSalActions.get(2);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.CopyTtlInCase", action.getImplementedInterface().getName());
action = mdSalActions.get(3);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.SetMplsTtlActionCase", action.getImplementedInterface().getName());
SetMplsTtlActionCase setMplsTtl = (SetMplsTtlActionCase) action;
Assert.assertEquals("Wrong mpls ttl", 4, setMplsTtl.getSetMplsTtlAction().getMplsTtl().intValue());
action = mdSalActions.get(4);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.DecMplsTtlCase", action.getImplementedInterface().getName());
action = mdSalActions.get(5);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PushVlanActionCase", action.getImplementedInterface().getName());
PushVlanActionCase pushVlan = (PushVlanActionCase) action;
Assert.assertEquals("Wrong ethertype", 16, pushVlan.getPushVlanAction().getEthernetType().intValue());
action = mdSalActions.get(6);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PopVlanActionCase", action.getImplementedInterface().getName());
action = mdSalActions.get(7);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PushMplsActionCase", action.getImplementedInterface().getName());
PushMplsActionCase pushMpls = (PushMplsActionCase) action;
Assert.assertEquals("Wrong ethertype", 17, pushMpls.getPushMplsAction().getEthernetType().intValue());
action = mdSalActions.get(8);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PopMplsActionCase", action.getImplementedInterface().getName());
PopMplsActionCase popMpls = (PopMplsActionCase) action;
Assert.assertEquals("Wrong ethertype", 18, popMpls.getPopMplsAction().getEthernetType().intValue());
action = mdSalActions.get(9);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.SetQueueActionCase", action.getImplementedInterface().getName());
SetQueueActionCase setQueue = (SetQueueActionCase) action;
Assert.assertEquals("Wrong queue-id", 1234, setQueue.getSetQueueAction().getQueueId().intValue());
action = mdSalActions.get(10);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.GroupActionCase", action.getImplementedInterface().getName());
GroupActionCase groupAction = (GroupActionCase) action;
Assert.assertEquals("Wrong group-id", 555, groupAction.getGroupAction().getGroupId().intValue());
action = mdSalActions.get(11);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.SetNwTtlActionCase", action.getImplementedInterface().getName());
SetNwTtlActionCase setNwTtl = (SetNwTtlActionCase) action;
Assert.assertEquals("Wrong nw ttl", 8, setNwTtl.getSetNwTtlAction().getNwTtl().intValue());
action = mdSalActions.get(12);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.DecNwTtlCase", action.getImplementedInterface().getName());
action = mdSalActions.get(13);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.SetFieldCase", action.getImplementedInterface().getName());
SetFieldCase setField = (SetFieldCase) action;
Assert.assertEquals("Wrong in port", "openflow:null:1", setField.getSetField().getInPort().getValue());
action = mdSalActions.get(14);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PushPbbActionCase", action.getImplementedInterface().getName());
PushPbbActionCase pushPbb = (PushPbbActionCase) action;
Assert.assertEquals("Wrong ethertype", 19, pushPbb.getPushPbbAction().getEthernetType().intValue());
action = mdSalActions.get(15);
Assert.assertEquals("Wrong action type", "org.opendaylight.yang.gen.v1.urn.opendaylight.action.types" + ".rev131112.action.action.PopPbbActionCase", action.getImplementedInterface().getName());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase in project openflowplugin by opendaylight.
the class OF10StatsReplyMessageFactoryTest method testFlow.
/**
* Testing OF10StatsReplyMessageFactory (Flow) for correct deserialization.
*/
@Test
public void testFlow() {
ByteBuf bb = BufferHelper.buildBuffer("00 01 00 01 00 68 01 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + "00 00 00 02 00 00 00 03 00 04 00 05 00 06 00 00 00 00 00 00 " + "FF 01 02 03 04 05 06 07 FF 01 02 03 04 05 06 07 FF 00 00 00 00 00 00 20 " + "00 00 00 08 00 01 00 02 00 01 00 08 00 03 00 00");
MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb);
BufferHelper.checkHeaderV10(builtByFactory);
Assert.assertEquals("Wrong type", 0x01, builtByFactory.getType().getIntValue());
Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE().booleanValue());
MultipartReplyFlowCase messageCase = (MultipartReplyFlowCase) builtByFactory.getMultipartReplyBody();
MultipartReplyFlow message = messageCase.getMultipartReplyFlow();
Assert.assertEquals("Wrong tableId", 1, message.getFlowStats().get(0).getTableId().intValue());
Assert.assertEquals("Wrong durationSec", 2, message.getFlowStats().get(0).getDurationSec().intValue());
Assert.assertEquals("Wrong durationNsec", 3, message.getFlowStats().get(0).getDurationNsec().intValue());
Assert.assertEquals("Wrong priority", 4, message.getFlowStats().get(0).getPriority().intValue());
Assert.assertEquals("Wrong idleTimeOut", 5, message.getFlowStats().get(0).getIdleTimeout().intValue());
Assert.assertEquals("Wrong hardTimeOut", 6, message.getFlowStats().get(0).getHardTimeout().intValue());
Assert.assertEquals("Wrong cookie", new BigInteger(1, new byte[] { (byte) 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }), message.getFlowStats().get(0).getCookie());
Assert.assertEquals("Wrong packetCount", new BigInteger(1, new byte[] { (byte) 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }), message.getFlowStats().get(0).getPacketCount());
Assert.assertEquals("Wrong byteCount", new BigInteger(1, new byte[] { (byte) 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 }), message.getFlowStats().get(0).getByteCount());
Action action1 = message.getFlowStats().get(0).getAction().get(0);
Assert.assertTrue("Wrong action type", action1.getActionChoice() instanceof OutputActionCase);
Assert.assertEquals("Wrong action port", 1, ((OutputActionCase) action1.getActionChoice()).getOutputAction().getPort().getValue().intValue());
Assert.assertEquals("Wrong action port", 2, ((OutputActionCase) action1.getActionChoice()).getOutputAction().getMaxLength().intValue());
Action action2 = message.getFlowStats().get(0).getAction().get(1);
Assert.assertTrue("Wrong action type", action2.getActionChoice() instanceof SetVlanVidCase);
Assert.assertEquals("Wrong action port", 3, ((SetVlanVidCase) action2.getActionChoice()).getSetVlanVidAction().getVlanVid().intValue());
Assert.assertTrue("Unread data", bb.readableBytes() == 0);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase in project openflowplugin by opendaylight.
the class PacketProcessingServiceImplTest method testBuildRequest.
@Test
public void testBuildRequest() throws Exception {
TransmitPacketInput transmitPacketInput = buildTransmitPacketInput();
final OfHeader request = packetProcessingService.buildRequest(new Xid(DUMMY_XID_VALUE), transmitPacketInput);
assertEquals(DUMMY_XID_VALUE, request.getXid());
assertTrue(request instanceof PacketOutInput);
final PacketOutInput input = (PacketOutInput) request;
assertEquals(OFConstants.OFP_NO_BUFFER, input.getBufferId());
assertEquals(1, input.getAction().size());
assertEquals(OutputActionCase.class, input.getAction().get(0).getActionChoice().getImplementedInterface());
final OutputActionCase actionChoice = (OutputActionCase) input.getAction().get(0).getActionChoice();
assertEquals(1, actionChoice.getOutputAction().getPort().getValue().intValue());
assertEquals(ULTIMATE_PAYLOAD, new String(input.getData()));
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase in project openflowplugin by opendaylight.
the class ActionsDeserializerTest method testDeserializeHeader.
/**
* Tests {@link AbstractActionDeserializer#deserializeHeader(ByteBuf)}.
*/
@Test
public void testDeserializeHeader() {
ByteBuf message = BufferHelper.buildBuffer("00 00 00 04 00 19 00 04");
// skip XID
message.skipBytes(4);
CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
List<Action> actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, message.readableBytes(), message, keyMaker, registry);
Assert.assertTrue("Wrong action type", actions.get(0).getActionChoice() instanceof OutputActionCase);
Assert.assertNull("Wrong action port", ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction());
Assert.assertNull("Wrong action max-length", ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction());
Assert.assertTrue("Wrong action type", actions.get(1).getActionChoice() instanceof SetFieldCase);
Assert.assertNull("Wrong action oxm field", ((SetFieldCase) actions.get(1).getActionChoice()).getSetFieldAction());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase in project openflowplugin by opendaylight.
the class InstructionsDeserializerTest method test.
/**
* Testing instructions translation.
*/
@Test
public void test() {
ByteBuf message = BufferHelper.buildBuffer("00 01 00 08 0A 00 00 00 00 02 00 18 00 00 00 00 " + "00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 30 00 05 00 08 00 00 00 00 00 06 00 08 " + "00 01 02 03 00 03 00 20 00 00 00 00 00 00 00 10 00 00 00 25 00 35 00 00 00 00 00 00 " + "00 16 00 08 00 00 00 50 00 04 00 18 00 00 00 00 00 15 00 08 00 00 00 25 00 0F 00 08 05 00 00 00");
// skip XID
message.skipBytes(4);
CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
List<Instruction> instructions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, message.readableBytes(), message, keyMaker, registry);
Instruction i1 = instructions.get(0);
Assert.assertTrue("Wrong type - i1", i1.getInstructionChoice() instanceof GotoTableCase);
Assert.assertEquals("Wrong table-id - i1", 10, ((GotoTableCase) i1.getInstructionChoice()).getGotoTable().getTableId().intValue());
Instruction i2 = instructions.get(1);
Assert.assertTrue("Wrong type - i2", i2.getInstructionChoice() instanceof WriteMetadataCase);
Assert.assertArrayEquals("Wrong metadata - i2", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 20"), ((WriteMetadataCase) i2.getInstructionChoice()).getWriteMetadata().getMetadata());
Assert.assertArrayEquals("Wrong metadata-mask - i2", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 30"), ((WriteMetadataCase) i2.getInstructionChoice()).getWriteMetadata().getMetadataMask());
Instruction i3 = instructions.get(2);
Assert.assertTrue("Wrong type - i3", i3.getInstructionChoice() instanceof ClearActionsCase);
Instruction i4 = instructions.get(3);
Assert.assertTrue("Wrong type - i4", i4.getInstructionChoice() instanceof MeterCase);
Assert.assertEquals("Wrong meterId - i4", 66051, ((MeterCase) i4.getInstructionChoice()).getMeter().getMeterId().intValue());
Instruction i5 = instructions.get(4);
Assert.assertTrue("Wrong type - i5", i5.getInstructionChoice() instanceof WriteActionsCase);
Assert.assertEquals("Wrong instructions - i5", 2, ((WriteActionsCase) i5.getInstructionChoice()).getWriteActions().getAction().size());
Action action1 = ((WriteActionsCase) i5.getInstructionChoice()).getWriteActions().getAction().get(0);
Assert.assertTrue("Wrong action", action1.getActionChoice() instanceof OutputActionCase);
Assert.assertEquals("Wrong action", 37, ((OutputActionCase) action1.getActionChoice()).getOutputAction().getPort().getValue().intValue());
Assert.assertEquals("Wrong action", 53, ((OutputActionCase) action1.getActionChoice()).getOutputAction().getMaxLength().intValue());
Action action2 = ((WriteActionsCase) i5.getInstructionChoice()).getWriteActions().getAction().get(1);
Assert.assertTrue("Wrong action", action2.getActionChoice() instanceof GroupCase);
Assert.assertEquals("Wrong action", 80, ((GroupCase) action2.getActionChoice()).getGroupAction().getGroupId().intValue());
Instruction i6 = instructions.get(5);
Assert.assertTrue("Wrong type - i6", i6.getInstructionChoice() instanceof ApplyActionsCase);
Assert.assertEquals("Wrong instructions - i6", 2, ((ApplyActionsCase) i6.getInstructionChoice()).getApplyActions().getAction().size());
action1 = ((ApplyActionsCase) i6.getInstructionChoice()).getApplyActions().getAction().get(0);
Assert.assertTrue("Wrong action", action1.getActionChoice() instanceof SetQueueCase);
Assert.assertEquals("Wrong action", 37, ((SetQueueCase) action1.getActionChoice()).getSetQueueAction().getQueueId().intValue());
action2 = ((ApplyActionsCase) i6.getInstructionChoice()).getApplyActions().getAction().get(1);
Assert.assertTrue("Wrong action", action2.getActionChoice() instanceof SetMplsTtlCase);
Assert.assertEquals("Wrong action", 5, ((SetMplsTtlCase) action2.getActionChoice()).getSetMplsTtlAction().getMplsTtl().shortValue());
}
Aggregations