88fd9b64bcf0904cb49f9cb030e2dc17c3f42ba6
[openflowplugin.git] / openflowjava / simple-client / src / main / java / org / opendaylight / openflowjava / protocol / impl / clients / ScenarioHandler.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowjava.protocol.impl.clients;
10
11 import io.netty.channel.ChannelHandlerContext;
12
13 import java.util.Deque;
14 import java.util.concurrent.BlockingQueue;
15 import java.util.concurrent.LinkedBlockingQueue;
16 import java.util.concurrent.TimeUnit;
17
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 /**
22  *
23  * @author michal.polkorab
24  *
25  */
26 public class ScenarioHandler extends Thread {
27
28     private static final Logger LOG = LoggerFactory.getLogger(ScenarioHandler.class);
29     private Deque<ClientEvent> scenario;
30     private final BlockingQueue<byte[]> ofMsg;
31     private ChannelHandlerContext ctx;
32     private int eventNumber;
33     private boolean scenarioFinished = false;
34     private int freeze = 2;
35     private long sleepBetweenTries = 100L;
36     private boolean finishedOK = true;
37
38     /**
39      *
40      * @param scenario {@link Deque}
41      */
42     public ScenarioHandler(Deque<ClientEvent> scenario) {
43         this.scenario = scenario;
44         ofMsg = new LinkedBlockingQueue<>();
45     }
46
47     public ScenarioHandler(Deque<ClientEvent> scenario, int freeze, long sleepBetweenTries){
48         this.scenario = scenario;
49         ofMsg = new LinkedBlockingQueue<>();
50         this.sleepBetweenTries = sleepBetweenTries;
51         this.freeze = freeze;
52     }
53
54     @Override
55     public void run() {
56         int freezeCounter = 0;
57         while (!scenario.isEmpty()) {
58             LOG.debug("Running event #{}", eventNumber);
59             ClientEvent peek = scenario.peekLast();
60             if (peek instanceof WaitForMessageEvent) {
61                 LOG.debug("WaitForMessageEvent");
62                 try {
63                     WaitForMessageEvent event = (WaitForMessageEvent) peek;
64                     event.setHeaderReceived(ofMsg.poll(2000, TimeUnit.MILLISECONDS));
65                 } catch (InterruptedException e) {
66                     LOG.error(e.getMessage(), e);
67                     break;
68                 }
69             } else if (peek instanceof SendEvent) {
70                 LOG.debug("Proceed - sendevent");
71                 SendEvent event = (SendEvent) peek;
72                 event.setCtx(ctx);
73             }
74             if (peek.eventExecuted()) {
75                 LOG.info("Scenario step finished OK, moving to next step.");
76                 scenario.removeLast();
77                 eventNumber++;
78                 freezeCounter = 0;
79                 finishedOK = true;
80             } else {
81                 freezeCounter++;
82             }
83             if (freezeCounter > freeze) {
84                 LOG.warn("Scenario frozen: {}", freezeCounter);
85                 LOG.warn("Scenario step not finished NOT OK!", freezeCounter);
86                 this.finishedOK = false;
87                 break;
88             }
89             try {
90                 sleep(sleepBetweenTries);
91             } catch (InterruptedException e) {
92                 LOG.error(e.getMessage(), e);
93             }
94         }
95         LOG.debug("Scenario finished");
96         synchronized (this) {
97             scenarioFinished = true;
98             this.notify();
99         }
100     }
101
102     /**
103      * @return true if scenario is done / empty
104      */
105     public boolean isEmpty() {
106         return scenario.isEmpty();
107     }
108
109     /**
110      * @return scenario
111      */
112     public Deque<ClientEvent> getScenario() {
113         return scenario;
114     }
115
116     /**
117      * @param scenario scenario filled with desired events
118      */
119     public void setScenario(Deque<ClientEvent> scenario) {
120         this.scenario = scenario;
121     }
122
123     /**
124      * @param ctx context which will be used for sending messages (SendEvents)
125      */
126     public void setCtx(ChannelHandlerContext ctx) {
127         this.ctx = ctx;
128     }
129
130     /**
131      * @param message received message that is compared to expected message
132      */
133     public void addOfMsg(byte[] message) {
134         ofMsg.add(message);
135     }
136
137     /**
138      * @return true is scenario is finished
139      */
140     public boolean isScenarioFinished() {
141         return scenarioFinished;
142     }
143
144     public boolean isFinishedOK() {
145         return finishedOK;
146     }
147 }