Passed
Push — 2.x ( 488b85...c0712a )
by Jordi
06:35
created

senaite.core.astm.consumer   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 53
dl 0
loc 79
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A PushConsumer.__init__() 0 3 1
A PushConsumer.get_sender_name() 0 8 3
B PushConsumer.process() 0 47 8
1
# -*- coding: utf-8 -*-
2
3
from bika.lims import api
4
from senaite.core import logger
5
from senaite.core.interfaces import IASTMImporter
6
from senaite.jsonapi.interfaces import IPushConsumer
7
from zope.component import adapter
8
from zope.component import getMultiAdapter
9
from zope.component import queryMultiAdapter
10
from zope.interface import Interface
11
from zope.interface import implementer
12
13
14
@adapter(Interface)
15
@implementer(IPushConsumer)
16
class PushConsumer(object):
17
    """Adapter that handles push requests for name "enaite.core.lis2a.import"
18
    """
19
    def __init__(self, data):
20
        self.data = data
21
        self.request = api.get_request()
22
23
    def get_sender_name(self, json_data, default=""):
24
        """Parse the sender name from the header record
25
        """
26
        header = json_data.get("H")
27
        if not isinstance(header, list) and len(header) != 1:
28
            return default
29
        sender = header[0].get("sender", {})
30
        return sender.get("name", default)
31
32
    def process(self):
33
        """Processes the LIS2-A compliant message.
34
        """
35
        # Extract LIS2-A messages from the data
36
        messages = self.data.get("messages")
37
        if not messages:
38
            raise ValueError("No messages found: {}".format(repr(self.data)))
39
40
        # Just in case we got a message instead of a list of messages
41
        if api.is_string(messages):
42
            messages = (messages,)
43
44
        logger.info("Received {} messages".format(len(messages)))
45
46
        # process messages
47
        for message in messages:
48
49
            json_data = api.parse_json(message, None)
50
            if json_data is None:
51
                logger.error("Invalid JSON message: %r" % message)
52
                continue
53
54
            sender_name = self.get_sender_name(json_data)
55
56
            # ASTM Data Importer Adapter
57
            importer = queryMultiAdapter(
58
                (json_data, message, self.request), IASTMImporter,
59
                name=sender_name)
60
            if importer is None:
61
                importer = getMultiAdapter(
62
                    (json_data, message, self.request), IASTMImporter)
63
64
            # import the data
65
            try:
66
                result = importer.import_data()
67
            except Exception as exc:
68
                message = "An error occured in '{}.import_data()'".format(
69
                    importer.__class__.__name__)
70
                logger.error(exc)
71
                continue
72
73
            if api.is_string(result):
74
                logger.error("Failed to import ASTM data with importer '{}'"
75
                             .format(importer.__class__.__name__))
76
                logger.error("Reason: {}".format(result))
77
78
        return True
79