unifying statistics manager api packages
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / queue / TicketProcessorFactoryImpl.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.api.openflow.md.core.ConnectionConductor;
16 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
17 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
18 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
19 import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
21 import org.opendaylight.yangtools.yang.binding.DataContainer;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import com.google.common.collect.ImmutableMap;
27
28 /**
29  * OfHeader to DataObject implementation
30  */
31 public class TicketProcessorFactoryImpl implements TicketProcessorFactory<OfHeader, DataObject> {
32
33     protected static final Logger LOG = LoggerFactory
34             .getLogger(TicketProcessorFactoryImpl.class);
35
36     protected Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping;
37     protected MessageSpy<DataContainer> spy;
38     protected TicketFinisher<DataObject> ticketFinisher;
39
40     /**
41      * @param translatorMapping the translatorMapping to set
42      */
43     @Override
44     public void setTranslatorMapping(
45             Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping) {
46         this.translatorMapping = ImmutableMap.copyOf(translatorMapping);
47     }
48
49     /**
50      * @param spy the spy to set
51      */
52     @Override
53     public void setSpy(MessageSpy<DataContainer> spy) {
54         this.spy = spy;
55     }
56
57     /**
58      * @param ticketFinisher the finisher to set
59      */
60     @Override
61     public void setTicketFinisher(TicketFinisher<DataObject> ticketFinisher) {
62         this.ticketFinisher = ticketFinisher;
63     }
64     
65     /**
66      * @param ticket
67      * @return runnable ticket processor
68      */
69     @Override
70     public Runnable createProcessor(final Ticket<OfHeader, DataObject> ticket) {
71
72         Runnable ticketProcessor = new Runnable() {
73             @Override
74             public void run() {
75                 LOG.debug("message received, type: {}", ticket.getMessage().getImplementedInterface().getSimpleName());
76                 List<DataObject> translate;
77                 try {
78                     translate = translate(ticket);
79                     ticket.getResult().set(translate);
80                     ticket.setDirectResult(translate);
81                     // spying on result
82                     if (spy != null) {
83                         spy.spyIn(ticket.getMessage());
84                         for (DataObject outMessage : translate) {
85                             spy.spyOut(outMessage);
86                         }
87                     }
88                 } catch (Exception e) {
89                     LOG.error("translation problem: {}", e.getMessage());
90                     ticket.getResult().setException(e);
91                 }
92                 LOG.debug("message processing done (type: {}, ticket: {})",
93                         ticket.getMessage().getImplementedInterface().getSimpleName(),
94                         System.identityHashCode(ticket));
95             }
96         };
97
98
99         return ticketProcessor;
100     }
101     
102     /**
103      * @param ticket
104      * @return runnable ticket processor
105      */
106     @Override
107     public Runnable createSyncProcessor(final Ticket<OfHeader, DataObject> ticket) {
108
109         Runnable ticketProcessor = new Runnable() {
110             @Override
111             public void run() {
112                 List<DataObject> translate;
113                 try {
114                     translate = translate(ticket);
115                     // spying on result
116                     if (spy != null) {
117                         spy.spyIn(ticket.getMessage());
118                         for (DataObject outMessage : translate) {
119                             spy.spyOut(outMessage);
120                         }
121                     }
122                     ticketFinisher.firePopNotification(translate);
123                 } catch (Exception e) {
124                     LOG.error("translation problem: {}", e.getMessage());
125                     ticket.getResult().setException(e);
126                 }
127             }
128         };
129
130
131         return ticketProcessor;
132     }
133     
134     
135     /**
136      * @param ticket 
137      *
138      */
139     @Override
140     public List<DataObject> translate(Ticket<OfHeader, DataObject> ticket) {
141         List<DataObject> result = new ArrayList<>();
142
143         OfHeader message = ticket.getMessage();
144         Class<? extends DataContainer> messageType = ticket.getMessage().getImplementedInterface();
145         ConnectionConductor conductor = ticket.getConductor();
146         Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> translators = null;
147         LOG.trace("translating ticket: {}, ticket: {}", messageType.getSimpleName(), System.identityHashCode(ticket));
148
149         Short version = message.getVersion();
150         if (version == null) {
151             throw new IllegalArgumentException("version is NULL");
152         }
153         TranslatorKey tKey = new TranslatorKey(version, messageType.getName());
154         translators = translatorMapping.get(tKey);
155
156         LOG.debug("translatorKey: {} + {}", version, messageType.getName());
157
158         if (translators != null) {
159             for (IMDMessageTranslator<OfHeader, List<DataObject>> translator : translators) {
160                 SwitchConnectionDistinguisher cookie = null;
161                 // Pass cookie only for PACKT_OfHeader
162                 if (messageType.equals("PacketInMessage.class")) {
163                     cookie = conductor.getAuxiliaryKey();
164                 }
165                 long start = System.nanoTime();
166                 List<DataObject> translatorOutput = translator.translate(cookie, conductor.getSessionContext(), message);
167                 long end = System.nanoTime();
168                 LOG.trace("translator: {} elapsed time {} ns",translator,end-start);
169                 if(translatorOutput != null && !translatorOutput.isEmpty()) {
170                     result.addAll(translatorOutput);
171                 }
172             }
173         } else {
174             LOG.warn("No translators for this message Type: {}", messageType);
175         }
176         
177         return result;
178     }
179 }