DO NOT MERGE: adding drop-test support for karaf
[openflowplugin.git] / test-common / src / main / java / org / opendaylight / openflowplugin / testcommon / AbstractDropTest.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, 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.openflowplugin.testcommon;
9
10 import java.util.Arrays;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
14
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 abstract class AbstractDropTest implements PacketProcessingListener, AutoCloseable {
41     private static final Logger LOG = LoggerFactory.getLogger(AbstractDropTest.class);
42
43     private static final AtomicIntegerFieldUpdater<AbstractDropTest> SENT_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AbstractDropTest.class, "_sent");
44     private volatile int _sent;
45
46     private static final AtomicIntegerFieldUpdater<AbstractDropTest> RCVD_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AbstractDropTest.class, "_rcvd");
47     private volatile int _rcvd;
48
49     private static final AtomicIntegerFieldUpdater<AbstractDropTest> EXCS_UPDATER = AtomicIntegerFieldUpdater.newUpdater(AbstractDropTest.class, "_excs");
50     private volatile int _excs;
51
52     public final DropTestStats getStats() {
53         return new DropTestStats(this._sent, this._rcvd, this._excs);
54     }
55
56     public final void clearStats(){
57         this._sent = 0;
58         this._rcvd = 0;
59         this._excs = 0;
60     }
61
62     @Override
63     public final void onPacketReceived(final PacketReceived notification) {
64         LOG.debug("onPacketReceived - Entering - {}", notification);
65
66         RCVD_UPDATER.incrementAndGet(this);
67
68         try {
69             final byte[] rawPacket = notification.getPayload();
70
71             // LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} payload {}",
72             //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(rawPacket));
73
74             final byte[] srcMac = Arrays.copyOfRange(rawPacket, 6, 12);
75
76             //LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} srcMac {}",
77             //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(srcMac));
78
79             final MatchBuilder match = new MatchBuilder();
80             final EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
81             final EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
82
83             //TODO: use HEX, use binary form
84             //Hex.decodeHex("000000000001".toCharArray());
85
86             ethSourceBuilder.setAddress(new MacAddress(DropTestUtils.macToString(srcMac)));
87             ethernetMatch.setEthernetSource(ethSourceBuilder.build());
88             match.setEthernetMatch(ethernetMatch.build());
89
90             final DropActionBuilder dab = new DropActionBuilder();
91             final DropAction dropAction = dab.build();
92             final ActionBuilder ab = new ActionBuilder();
93             ab.setOrder(0);
94             ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
95
96             // Add our drop action to a list
97             final List<Action> actionList = Collections.singletonList(ab.build());
98
99             // Create an Apply Action
100             final ApplyActionsBuilder aab = new ApplyActionsBuilder();
101             aab.setAction(actionList);
102
103             // Wrap our Apply Action in an Instruction
104             final InstructionBuilder ib = new InstructionBuilder();
105             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()).setOrder(0);
106
107             // Put our Instruction in a list of Instructions
108             final InstructionsBuilder isb = new InstructionsBuilder();
109             final List<Instruction> instructions = Collections.singletonList(ib.build());
110             isb.setInstruction(instructions);
111
112             // Get the Ingress nodeConnectorRef
113             final NodeConnectorRef ncr = notification.getIngress();
114
115             // Get the instance identifier for the nodeConnectorRef
116             final InstanceIdentifier<?> ncri = ncr.getValue();
117
118             // Get the instanceID for the Node in the tree above us
119             final NodeKey node = ncri.firstKeyOf(Node.class, NodeKey.class);
120
121             processPacket(node, match.build(), isb.build());
122             SENT_UPDATER.incrementAndGet(this);
123         } catch (Exception e) {
124             // TODO Auto-generated catch block
125             LOG.error("Failed to process packet", e);
126             EXCS_UPDATER.incrementAndGet(this);
127         }
128
129         LOG.debug("onPacketReceived - Leaving", notification);
130     }
131
132     protected abstract void processPacket(NodeKey node, Match match, Instructions instructions);
133 }