BUG-542 - adding overall statictics
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / queue / TicketProcessorFactory.java
1 /**
2  * Copyright (c) 2013 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.openflow.md.queue;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
16 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
17 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
18 import org.opendaylight.openflowplugin.openflow.md.core.TranslatorKey;
19 import org.opendaylight.yangtools.yang.binding.DataContainer;
20 import org.opendaylight.yangtools.yang.binding.DataObject;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * @param <IN>
26  * @param <OUT>
27  */
28 public class TicketProcessorFactory<IN extends DataObject, OUT extends DataObject> {
29
30     protected static final Logger LOG = LoggerFactory
31             .getLogger(TicketProcessorFactory.class);
32
33     protected VersionExtractor<IN> versionExtractor;
34     protected RegisteredTypeExtractor<IN> registeredTypeExtractor;
35     protected Map<TranslatorKey, Collection<IMDMessageTranslator<IN, List<OUT>>>> translatorMapping;
36     protected MessageSpy<DataContainer> spy;
37
38     /**
39      * @param versionExtractor the versionExtractor to set
40      */
41     public void setVersionExtractor(VersionExtractor<IN> versionExtractor) {
42         this.versionExtractor = versionExtractor;
43     }
44
45     /**
46      * @param registeredTypeExtractor the registeredTypeExtractor to set
47      */
48     public void setRegisteredTypeExtractor(
49             RegisteredTypeExtractor<IN> registeredTypeExtractor) {
50         this.registeredTypeExtractor = registeredTypeExtractor;
51     }
52
53     /**
54      * @param translatorMapping the translatorMapping to set
55      */
56     public void setTranslatorMapping(
57             Map<TranslatorKey, Collection<IMDMessageTranslator<IN, List<OUT>>>> translatorMapping) {
58         this.translatorMapping = translatorMapping;
59     }
60
61     /**
62      * @param spy the spy to set
63      */
64     public void setSpy(MessageSpy<DataContainer> spy) {
65         this.spy = spy;
66     }
67
68
69     /**
70      * @param ticket
71      * @return runnable ticket processor
72      */
73     public Runnable createProcessor(final Ticket<IN, OUT> ticket) {
74
75         Runnable ticketProcessor = new Runnable() {
76             @Override
77             public void run() {
78                 LOG.debug("message received, type: {}", registeredTypeExtractor.extractRegisteredType(
79                         ticket.getMessage()).getSimpleName());
80                 List<OUT> translate;
81                 try {
82                     translate = translate();
83                     ticket.getResult().set(translate);
84                     // spying on result
85                     if (spy != null) {
86                         spy.spyIn(ticket.getMessage());
87                         for (OUT outMessage : ticket.getResult().get()) {
88                             spy.spyOut(outMessage);
89                         }
90                     }
91                 } catch (Exception e) {
92                     LOG.error("translation problem: {}", e.getMessage());
93                     ticket.getResult().setException(e);
94                 }
95                 LOG.debug("message processing done (type: {}, ticket: {})",
96                         registeredTypeExtractor.extractRegisteredType(ticket.getMessage()).getSimpleName(),
97                         System.identityHashCode(ticket));
98             }
99
100             /**
101              *
102              */
103             private List<OUT> translate() {
104                 List<OUT> result = new ArrayList<>();
105
106                 IN message = ticket.getMessage();
107                 Class<? extends IN> messageType = registeredTypeExtractor.extractRegisteredType(ticket.getMessage());
108                 ConnectionConductor conductor = ticket.getConductor();
109                 Collection<IMDMessageTranslator<IN, List<OUT>>> translators = null;
110                 LOG.debug("translating ticket: {}, ticket: {}", messageType.getSimpleName(), System.identityHashCode(ticket));
111
112                 Short version = versionExtractor.extractVersion(message);
113                 if (version == null) {
114                     throw new IllegalArgumentException("version is NULL");
115                 }
116                 TranslatorKey tKey = new TranslatorKey(version, messageType.getName());
117                 translators = translatorMapping.get(tKey);
118
119                 LOG.debug("translatorKey: {} + {}", version, messageType.getName());
120
121                 if (translators != null) {
122                     for (IMDMessageTranslator<IN, List<OUT>> translator : translators) {
123                         SwitchConnectionDistinguisher cookie = null;
124                         // Pass cookie only for PACKT_IN
125                         if (messageType.equals("PacketInMessage.class")) {
126                             cookie = conductor.getAuxiliaryKey();
127                         }
128                         long start = System.nanoTime();
129                         List<OUT> translatorOutput = translator.translate(cookie, conductor.getSessionContext(), message);
130                         long end = System.nanoTime();
131                         LOG.debug("translator: {} elapsed time {} ns",translator,end-start);
132                         if(translatorOutput != null && !translatorOutput.isEmpty()) {
133                             result.addAll(translatorOutput);
134                         }
135                     }
136                 } else {
137                     LOG.warn("No translators for this message Type: {}", messageType);
138                 }
139                 return result;
140             }
141         };
142
143         return ticketProcessor;
144     }
145 }