Fix double translation of messages.
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / queue / TicketProcessorFactory.java
index f3b50b8a0ea0153b7bc1fe0919eee134aa2bb067..ff37cba3151956be7c7ac5f7f77a312d569d3f76 100644 (file)
@@ -20,38 +20,76 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * @author mirehak
- *
+ * @param <IN>
+ * @param <OUT>
  */
-public abstract class TicketProcessorFactory {
+public class TicketProcessorFactory<IN, OUT> {
 
     protected static final Logger LOG = LoggerFactory
             .getLogger(TicketProcessorFactory.class);
+    
+    protected VersionExtractor<IN> versionExtractor;
+    protected RegisteredTypeExtractor<IN> registeredTypeExtractor;
+    protected Map<TranslatorKey, Collection<IMDMessageTranslator<IN, List<OUT>>>> translatorMapping;
+    protected MessageSpy<IN, OUT> spy;
+    
+    /**
+     * @param versionExtractor the versionExtractor to set
+     */
+    public void setVersionExtractor(VersionExtractor<IN> versionExtractor) {
+        this.versionExtractor = versionExtractor;
+    }
+
+    /**
+     * @param registeredTypeExtractor the registeredTypeExtractor to set
+     */
+    public void setRegisteredTypeExtractor(
+            RegisteredTypeExtractor<IN> registeredTypeExtractor) {
+        this.registeredTypeExtractor = registeredTypeExtractor;
+    }
+
+    /**
+     * @param translatorMapping the translatorMapping to set
+     */
+    public void setTranslatorMapping(
+            Map<TranslatorKey, Collection<IMDMessageTranslator<IN, List<OUT>>>> translatorMapping) {
+        this.translatorMapping = translatorMapping;
+    }
+
+    /**
+     * @param spy the spy to set
+     */
+    public void setSpy(MessageSpy<IN, OUT> spy) {
+        this.spy = spy;
+    }
+
 
     /**
      * @param ticket
-     * @param versionExtractor 
-     * @param translatorMapping
      * @return runnable ticket processor
      */
-    public static <IN, OUT> Runnable createProcessor(
-            final Ticket<IN, OUT> ticket,
-            final VersionExtractor<IN> versionExtractor,
-            final Map<TranslatorKey, Collection<IMDMessageTranslator<IN, OUT>>> translatorMapping) {
-        return new Runnable() {
+    public Runnable createProcessor(final Ticket<IN, OUT> ticket) {
+        
+        Runnable ticketProcessor = new Runnable() {
             @Override
             public void run() {
-                LOG.debug("message received, type: {}", ticket.getRegisteredMessageType().getSimpleName());
+                LOG.debug("message received, type: {}", registeredTypeExtractor.extractRegisteredType(
+                        ticket.getMessage()).getSimpleName());
                 List<OUT> translate;
                 try {
                     translate = translate();
                     ticket.getResult().set(translate);
+                    // spying on result
+                    if (spy != null) {
+                        spy.spyIn(ticket.getMessage());
+                        spy.spyOut(ticket.getResult().get());
+                    }
                 } catch (Exception e) {
                     LOG.error("translation problem: {}", e.getMessage());
                     ticket.getResult().setException(e);
                 }
-                LOG.debug("message processing done (type: {}, ticket: {})", 
-                        ticket.getRegisteredMessageType().getSimpleName(), 
+                LOG.debug("message processing done (type: {}, ticket: {})",
+                        registeredTypeExtractor.extractRegisteredType(ticket.getMessage()).getSimpleName(),
                         System.identityHashCode(ticket));
             }
 
@@ -60,30 +98,33 @@ public abstract class TicketProcessorFactory {
              */
             private List<OUT> translate() {
                 List<OUT> result = new ArrayList<>();
-                
+
                 IN message = ticket.getMessage();
-                Class<? extends IN> messageType = ticket.getRegisteredMessageType();
+                Class<? extends IN> messageType = registeredTypeExtractor.extractRegisteredType(ticket.getMessage());
                 ConnectionConductor conductor = ticket.getConductor();
-                Collection<IMDMessageTranslator<IN, OUT>> translators = null;
+                Collection<IMDMessageTranslator<IN, List<OUT>>> translators = null;
                 LOG.debug("translating ticket: {}, ticket: {}", messageType.getSimpleName(), System.identityHashCode(ticket));
-                
+
                 Short version = versionExtractor.extractVersion(message);
                 if (version == null) {
-                   throw new IllegalArgumentException("version is NULL"); 
+                    throw new IllegalArgumentException("version is NULL");
                 }
                 TranslatorKey tKey = new TranslatorKey(version, messageType.getName());
                 translators = translatorMapping.get(tKey);
-                
+
                 LOG.debug("translatorKey: {} + {}", version, messageType.getName());
 
                 if (translators != null) {
-                    for (IMDMessageTranslator<IN, OUT> translator : translators) {
+                    for (IMDMessageTranslator<IN, List<OUT>> translator : translators) {
                         SwitchConnectionDistinguisher cookie = null;
                         // Pass cookie only for PACKT_IN
                         if (messageType.equals("PacketInMessage.class")) {
                             cookie = conductor.getAuxiliaryKey();
                         }
-                        result.add(translator.translate(cookie, conductor.getSessionContext(), message));
+                        List<OUT> translatorOutput = translator.translate(cookie, conductor.getSessionContext(), message);
+                        if(translatorOutput != null && !translatorOutput.isEmpty()) {
+                            result.addAll(translatorOutput);
+                        }
                     }
                 } else {
                     LOG.warn("No translators for this message Type: {}", messageType);
@@ -91,5 +132,7 @@ public abstract class TicketProcessorFactory {
                 return result;
             }
         };
+
+        return ticketProcessor;
     }
 }