messages.py 71.2 KB
Newer Older
1 2 3
# -*- coding: utf-8 -*-

"""
4 5 6 7

About the library:
-----------------

8 9 10 11 12 13 14 15 16
This module provides the API message formats used in F-Interop.

The idea is to be able to have an
- organized and centralized way of dealing with the big amount of messages formats used in the platform;
- to be able to import (or just copy/paste) these messages formats from any component in the F-Interop platform,
- re-use this also for the integration testing;
- to have version control the messages e.g. messages_testcase_start API v1 and API v2;
- to have a direct way of exporting this as doc.

17 18 19 20 21 22 23 24

F-Interop conventions:
---------------------
- if event is a service request then the routing key (r_key) is control.someFunctionality.service
- a reply to a service will be on topic/r_key : control.someFunctionality.service.reply
- reply.correlation_id = request.correlation_id


25 26
Usage:
------
27
>>> from messages import * # doctest: +SKIP
Federico Sismondi's avatar
Federico Sismondi committed
28
>>> m = MsgTestCaseSkip(testcase_id = 'some_testcase_id')
29
>>> m
30
MsgTestCaseSkip(_api_version = 1.0.1, _type = testcoordination.testcase.skip, description = Skip testcase, node = someNode, testcase_id = some_testcase_id, )
31 32
>>> m.routing_key
'control.testcoordination'
33 34
>>> m.message_id # doctest: +SKIP
'802012eb-24e3-45c4-9dcc-dc293c584f63'
35
>>> m.testcase_id
Federico Sismondi's avatar
Federico Sismondi committed
36
'some_testcase_id'
37

38
# also we can modify some of the fields (rewrite the default ones)
Federico Sismondi's avatar
Federico Sismondi committed
39
>>> m = MsgTestCaseSkip(testcase_id = 'TD_COAP_CORE_03')
40
>>> m
41
MsgTestCaseSkip(_api_version = 1.0.1, _type = testcoordination.testcase.skip, description = Skip testcase, node = someNode, testcase_id = TD_COAP_CORE_03, )
42
>>> m.testcase_id
Federico Sismondi's avatar
Federico Sismondi committed
43
'TD_COAP_CORE_03'
44

45 46
# and even export the message in json format (for example for sending the message though the amqp event bus)
>>> m.to_json()
47
'{"_api_version": "1.0.1", "_type": "testcoordination.testcase.skip", "description": "Skip testcase", "node": "someNode", "testcase_id": "TD_COAP_CORE_03"}'
Federico Sismondi's avatar
Federico Sismondi committed
48

49
# We can use the Message class to import json into Message objects:
Federico Sismondi's avatar
Federico Sismondi committed
50 51
>>> m=MsgTestSuiteStart()
>>> m.to_json()
52
'{"_api_version": "1.0.1", "_type": "testcoordination.testsuite.start", "description": "Event test suite START"}'
Federico Sismondi's avatar
Federico Sismondi committed
53 54 55
>>> json_message = m.to_json()
>>> obj=Message.from_json(json_message)
>>> type(obj)
56
<class 'messages.MsgTestSuiteStart'>
57

58
# We can use the library for generating error responses:
59 60 61 62 63 64
# the request:
>>> m = MsgSniffingStart()
>>>
# the error reply (note that we pass the message of the request to build the reply):
>>> err = MsgErrorReply(m)
>>> err
65
MsgErrorReply(_api_version = 1.0.1, _type = sniffing.start, error_code = Some error code TBD, error_message = Some error message TBD, ok = False, )
66 67 68 69 70 71 72 73 74
>>> m.reply_to
'control.sniffing.service.reply'
>>> err.routing_key
'control.sniffing.service.reply'

>>> m.correlation_id # doctest: +SKIP
'360b0f67-4455-43e3-a00f-eca91f2e84da'
>>> err.correlation_id # doctest: +SKIP
'360b0f67-4455-43e3-a00f-eca91f2e84da'
Federico Sismondi's avatar
Federico Sismondi committed
75

76 77 78
"""

from collections import OrderedDict
79
import time
80 81 82
import json
import uuid

83
API_VERSION = '1.0.1'
84

85 86 87 88 89 90 91 92 93 94

# TODO use metaclasses instead?
class NonCompliantMessageFormatError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)


Federico Sismondi's avatar
Federico Sismondi committed
95
class Message(object):
96
    def __init__(self, **kwargs):
97 98 99
        global API_VERSION

        # hard copy the message template
100
        self._msg_data = {k: v for k, v in self._msg_data_template.items()}
101

102 103
        # init properties
        self._properties = dict(
104 105 106
            content_type="application/json",
            message_id=str(uuid.uuid4()),
            timestamp=int(time.time())
107 108
        )

109
        try:
110 111 112
            if self.routing_key.endswith(".service"):
                self._properties["reply_to"] = "%s.%s" % (self.routing_key, "reply")
                self._properties["correlation_id"] = self._properties["message_id"]
113
        except AttributeError:
114
            pass
115

116
        # rewrite default data fields with the passed args
117 118 119
        self._msg_data.update(kwargs)

        # add API's version
120
        if "_api_version" not in self._msg_data:
121
            self._msg_data["_api_version"] = API_VERSION
122 123 124 125 126

        # add values as objects attributes
        for key in self._msg_data:
            setattr(self, key, self._msg_data[key])

127 128 129 130
        # add props as objects attributes
        for key in self._properties:
            setattr(self, key, self._properties[key])

131 132
    def to_dict(self):
        resp = {}
133 134
        # let's use sorted so API returns items inside always in the same order
        for field in sorted(self._msg_data.keys()):
135
            resp[field] = getattr(self, field)
136

137
        return OrderedDict(sorted(resp.items(), key=lambda t: t[0]))  # sorted by key
138 139 140 141

    def to_json(self):
        return json.dumps(self.to_dict())

142
    def get_properties(self):
143 144 145 146
        resp = OrderedDict()
        for field in self._properties:
            resp[field] = getattr(self, field)
        return resp
147

148
    def __str__(self):
149 150 151 152 153 154 155
        s = " - " * 20 + "\n"
        s += "Message routing key: %s" % self.routing_key
        s += "\n -  -  - \n"
        s += "Message properties: %s" % json.dumps(self.get_properties(), indent=4, )
        s += "\n -  -  - \n"
        s += "Message body: %s" % json.dumps(self.to_dict(), indent=4, )
        s += "\n" + " - " * 20
156
        return s
157

158 159 160 161 162
    def update_properties(self, **kwargs):
        for key, value in kwargs.items():
            if key in self._properties:
                setattr(self, key, value)

163 164
    @classmethod
    def from_json(cls, body):
165 166 167 168 169 170 171 172 173 174
        """
        :param body: json string or string encoded as utf-8
        :return:  Message object generated from the body
        :raises NonCompliantMessageFormatError: If the message cannot be build from the provided json
        """

        if type(body) is str:
            message_dict = json.loads(body)
        # Note: pika re-encodes json.dumps strings as utf-8 for some reason, the following line undoes this
        elif type(body) is bytes:
175
            message_dict = json.loads(body.decode("utf-8"))
176
        else:
177
            raise NonCompliantMessageFormatError("Not a Json")
178

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
        # check fist if it's a response
        if "ok" in message_dict:
            # cannot build a complete reply message just from the json representation
            return

        return cls.from_dict(message_dict)

    @classmethod
    def from_dict(cls, message_dict):
        """
        :param body: dict
        :return:  Message object generated from the body
        :raises NonCompliantMessageFormatError: If the message cannot be build from the provided json
        """
        assert type(message_dict) is dict

195
        # check fist if it's a response
196
        if "ok" in message_dict:
197
            # cannot build a complete reply message just from the json representation
198
            return
199

200
        message_type = message_dict["_type"]
201

202 203 204
        if message_type in message_types_dict:
            return message_types_dict[message_type](**message_dict)
        else:
205 206
            raise NonCompliantMessageFormatError("Cannot load json message: %s" % str(message_dict))

207
    def __repr__(self):
208
        ret = "%s(" % self.__class__.__name__
209
        for key, value in self.to_dict().items():
210 211
            ret += "%s = %s, " % (key, value)
        ret += ")"
212 213
        return ret

214

215 216 217 218 219
class MsgReply(Message):
    """
    Auxiliary class which creates replies messages with fields based on the request.
    Routing key, corr_id and _type are generated based on the request message
    """
220

221 222 223 224 225 226 227
    def __init__(self, request_message, **kwargs):
        assert request_message

        self.routing_key = request_message.routing_key + ".reply"

        # if not data template, then let's build one for a reply
        # (possible when creating a MsgReply directly and not by using subclass)
228
        if not hasattr(self, "_msg_data_template"):
229
            self._msg_data_template = {
230
                "_type": request_message._type,
231
                "ok": True,
232 233
            }

234
        super(MsgReply, self).__init__(**kwargs)
235

236
        # overwrite correlation id template and attribute
237
        self._properties["correlation_id"] = request_message.correlation_id
238 239 240 241 242
        self.correlation_id = request_message.correlation_id


class MsgErrorReply(MsgReply):
    """
243
    see section "F-Interop conventions" on top
244
    """
245

246 247
    def __init__(self, request_message, **kwargs):
        assert request_message
248
        # msg_data_template doesnt include _type cause this class is generic, we can only get this at init from request
249
        # so, let's copy the _type from request and let the MsgReply handle the rest of the fields
250
        self._msg_data_template["_type"] = request_message._type
251
        super(MsgErrorReply, self).__init__(request_message, **kwargs)
252 253

    _msg_data_template = {
254
        "ok": False,
255
        "error_message": "Some error message TBD",
256
        "error_code": "Some error code TBD"
257 258
    }

Federico Sismondi's avatar
Federico Sismondi committed
259

260
# # # # # # CORE API messages # # # # #
261 262

class MsgOrchestratorVersionReq(Message):
263 264 265 266 267 268 269 270 271
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for returning current version of SO
    """
272 273 274 275 276
    routing_key = "control.orchestrator.service"

    _msg_data_template = {
        "_type": "ochestrator.version.request"
    }
277

Federico Sismondi's avatar
Federico Sismondi committed
278

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
class MsgOrchestratorUsersList(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for returning user list of SO
    """
    routing_key = "control.orchestrator.users.list.service"

    _msg_data_template = {
        "_type": "orchestrator.users.list.request"
    }


class MsgOrchestratorUserAdd(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for adding a user to SO
    """
    routing_key = "control.orchestrator.users.add.service"

    _msg_data_template = {
        "_type": "orchestrator.users.add.request"
    }


class MsgOrchestratorUserDelete(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for deleting a user from SO
    """
    routing_key = "control.orchestrator.users.delete.service"

    _msg_data_template = {
        "_type": "orchestrator.users.delete.request"
    }


class MsgOrchestratorUserGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting a user from SO
    """
    routing_key = "control.orchestrator.users.get.service"

    _msg_data_template = {
        "_type": "orchestrator.users.get.request"
    }


class MsgOrchestratorSessionsList(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for listing sessions from SO
    """
    routing_key = "control.orchestrator.sessions.list.service"

    _msg_data_template = {
        "_type": "orchestrator.sessions.list.request"
    }


class MsgOrchestratorSessionsGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting a session from SO
    """
    routing_key = "control.orchestrator.sessions.get.service"

    _msg_data_template = {
        "_type": "orchestrator.sessions.get.request"
    }


class MsgOrchestratorSessionsAdd(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for adding a session to SO
    """
    routing_key = "control.orchestrator.sessions.add.service"

    _msg_data_template = {
        "_type": "orchestrator.sessions.add.request"
    }


class MsgOrchestratorSessionsDelete(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for deleting a session to SO
    """
    routing_key = "control.orchestrator.sessions.delete.service"

    _msg_data_template = {
        "_type": "orchestrator.sessions.delete.request"
    }


class MsgOrchestratorSessionsUpdate(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for updating a session from SO
    """
    routing_key = "control.orchestrator.sessions.update.service"

    _msg_data_template = {
        "_type": "orchestrator.sessions.update.request"
    }


class MsgOrchestratorTestsGet(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting tests from SO
    """
    routing_key = "control.orchestrator.tests.get.service"

    _msg_data_template = {
        "_type": "orchestrator.tests.get.request"
    }


class MsgOrchestratorTestsGetContributorName(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: UI -> SO

    Description: Message for getting tests from SO with contributor and name
    """
    routing_key = "control.orchestrator.tests.get_contributor_name.service"

    _msg_data_template = {
        "_type": "orchestrator.tests.get_contributor_name.request"
    }


466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
# # # # # # UI API messages # # # # # # # #

class MsgUiRequestTextInput(Message):
    """
    Requirements: ...

    Type: Event

    Pub/Sub: TT -> UI

    Description: Message for requesting action or information to user
    """
    routing_key = "ui.any.request"

    _msg_data_template = {
        "_type": "ui.any.request.text.input",
        "fields": [
            {"name": "input_name",
             "type": "text"},
        ]
    }

488

489
# # # # # # AGENT MESSAGES # # # # # #
Federico Sismondi's avatar
Federico Sismondi committed
490

491

Federico Sismondi's avatar
Federico Sismondi committed
492 493
class MsgAgentTunStart(Message):
    """
494
    Requirements: Testing Tool MAY implement (if IP tun needed)
Federico Sismondi's avatar
Federico Sismondi committed
495

496
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
497

498
    Pub/Sub: Testing Tool -> Agent
Federico Sismondi's avatar
Federico Sismondi committed
499

500
    Description: Message for triggering start IP tun interface in OS where the agent is running
Federico Sismondi's avatar
Federico Sismondi committed
501
    """
502
    routing_key = "control.tun.toAgent.agent_TT"
Federico Sismondi's avatar
Federico Sismondi committed
503 504

    _msg_data_template = {
505 506 507 508
        "_type": "tun.start",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
509
        "ipv6_no_forwarding": False,
510 511 512
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
Federico Sismondi's avatar
Federico Sismondi committed
513 514 515
    }


516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
class MsgAgentSerialStarted(Message):
    """
    Description: Message for indicating that agent serial interface has been started

    Type: Event

    Pub/Sub: Testing Tool -> Agent

    Description: TBD
    """
    routing_key = "control.serial.from.tbd"

    _msg_data_template = {
        "_type": "serial.started",
        "name": "tbd",
        "port": "tbd",
        "boudrate": "tbd",
    }


Federico Sismondi's avatar
Federico Sismondi committed
536 537
class MsgAgentTunStarted(Message):
    """
538
    Description: Message for indicating that agent tun has been started
Federico Sismondi's avatar
Federico Sismondi committed
539

540
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
541

542
    Pub/Sub: Agent -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
543

544
    Description: TBD
Federico Sismondi's avatar
Federico Sismondi committed
545
    """
546
    routing_key = "control.tun.from.tbd"
Federico Sismondi's avatar
Federico Sismondi committed
547 548

    _msg_data_template = {
549 550 551 552 553 554 555
        "_type": "tun.started",
        "name": "agent_TT",
        "ipv6_prefix": "bbbb",
        "ipv6_host": ":3",
        "ipv4_host": None,
        "ipv4_network": None,
        "ipv4_netmask": None,
556
        "ipv6_no_forwarding": False,
Federico Sismondi's avatar
Federico Sismondi committed
557 558
    }

559

560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
class MsgPacketInjectRaw(Message):
    """
    Description: Message to be captured by the agent an push into the correct embedded interface (e.g. tun, serial, etc..)

    Type: Event

    Pub/Sub: Testing Tool -> Agent

    Description: TBD
    """
    routing_key = None  # depends on the agent_id and the agent interface being used, re-write after creation

    _msg_data_template = {
        "_type": "packet.to_inject.raw",
        "timestamp": "1488586183.45",
        "interface_name": "tun0",
        "data": [96, 0, 0, 0, 0, 36, 0, 1, 254, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 2, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 22, 58, 0, 5, 2, 0, 0, 1, 0, 143, 0, 112, 7, 0, 0, 0, 1, 4, 0, 0, 0, 255, 2, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]}


581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
class MsgPacketSniffedRaw(Message):
    """
    Description: Message captured by the agent in one of its embedded interfaces (e.g. tun, serial, etc..)

    Type: Event

    Pub/Sub: Agent -> Testing Tool

    Description: TBD
    """
    routing_key = None  # depends on the agent_id and the agent interface being used, re-write after creation

    _msg_data_template = {
        "_type": "packet.sniffed.raw",
        "timestamp": "1488586183.45",
        "interface_name": "tun0",
        "data": [96, 0, 0, 0, 0, 36, 0, 1, 254, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 2, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 22, 58, 0, 5, 2, 0, 0, 1, 0, 143, 0, 112, 7, 0, 0, 0, 1, 4, 0, 0, 0, 255, 2, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]}
600

601 602

# # # # # # SESSION MESSAGES # # # # # #
603

604
class MsgTestingToolTerminate(Message):
605
    """
606
    Requirements: TT MUST listen to event, and handle a gracefully termination of all it's processes
Federico Sismondi's avatar
Federico Sismondi committed
607

608
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
609

610
    Pub/Sub: GUI, (or Orchestrator) -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
611

612
    Description: Testing tool should stop all it's processes gracefully.
613
    """
614
    routing_key = "control.session"
615 616

    _msg_data_template = {
617
        "_type": "testingtool.terminate",
618
        "description": "Event TERMINATE testing tool execution"
619 620 621 622 623
    }


class MsgTestingToolReady(Message):
    """
624
    Requirements: TT MUST publish event as soon as TT is up and listening on the event bus
Federico Sismondi's avatar
Federico Sismondi committed
625

626
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
627

628
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
629

630
    Description: Used to indicate to the GUI that testing is ready to start the test suite
631
    """
632
    routing_key = "control.session"
633 634

    _msg_data_template = {
635 636
        "_type": "testingtool.ready",
        "description": "Event Testing tool READY to start test suite."
637 638 639 640 641
    }


class MsgTestingToolComponentReady(Message):
    """
642
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
643

644
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
645

646
    Pub/Sub: Any Testing tool's component -> Test Coordinator
Federico Sismondi's avatar
Federico Sismondi committed
647

648
    Description: Once a testing tool's component is ready, it should publish a compoennt ready message
649
    """
650
    routing_key = "control.session"
651 652

    _msg_data_template = {
653
        "_type": "testingtool.component.ready",
654
        "component": "SomeComponent",
655
        "description": "Component READY to start test suite."
656 657 658
    }


659 660 661 662 663 664 665 666 667 668
class MsgSessionChat(Message):
    """
    Requirements: GUI should implement

    Type: Event

    Pub/Sub: UI 1 (2) -> UI 2 (1)

    Description: Generic descriptor of chat messages
    """
669
    routing_key = "control.session"
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692

    _msg_data_template = {
        "_type": "chat",
        "user_name": "Ringo",
        "iut_node": "tbd",
        "description": "I've got blisters on my fingers!"
    }


class MsgSessionLog(Message):
    """
    Requirements: Testing Tool SHOULD implement

    Type: Event

    Pub/Sub: Any Testing tool's component -> user/devs interfaces

    Description: Generic descriptor of log messages
    """
    routing_key = "log.warning.the_drummer"

    _msg_data_template = {
        "_type": "log",
Federico Sismondi's avatar
Federico Sismondi committed
693
        "component": "misc",
694
        "message": "I've got blisters on my fingers!"
695 696 697
    }


698 699
class MsgSessionConfiguration(Message):
    """
700
    Requirements: TT MUST listen to event, and configure accordingly
701 702 703 704 705

    Type: Event

    Pub/Sub: Orchestrator -> Testing Tool

706
    Description: TT MUST listen to this message and configure the testsuite correspondingly
707 708
    """
    routing_key = "control.session"
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
    _msg_data_template = {
        "_type": "session.configuration",
        "session_id": "666",
        "configuration": {
            'testsuite.testcases': [
                'someTestCaseId1',
                'someTestCaseId2'
            ]
        },
        "testing_tools": "f-interop/someTestToolId",
        "users": [
            "u1",
            "f-interop"
        ],
    }


# TODO deprecate this in favor of the generic MsgSessionConfiguration
728
class MsgInteropSessionConfiguration(Message):
729
    """
730
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
731

732
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
733

734
    Pub/Sub: Orchestrator -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
735

736
    Description: TT MUST listen to this message and configure the testsuite correspondingly
737
    """
738
    routing_key = "control.session"
739 740

    _msg_data_template = {
741 742
        "_type": "session.interop.configuration",
        "session_id": "TBD",
743 744 745 746 747 748 749 750
        "configuration":
            {
                'testsuite.testcases': [
                    'http://doc.f-interop.eu/tests/TD_COAP_CORE_01',
                    'http://doc.f-interop.eu/tests/TD_COAP'
                ]
            },

751
        "testing_tools": "f-interop/interoperability-coap",
752
        "users": [
753 754 755
            "u1",
            "f-interop"
        ],
756
        "tests": [
757
            {
Federico Sismondi's avatar
Federico Sismondi committed
758
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01",
759
                "settings": {}
760 761
            },
            {
Federico Sismondi's avatar
Federico Sismondi committed
762
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_02",
763 764 765
                "settings": {}
            },
            {
Federico Sismondi's avatar
Federico Sismondi committed
766
                "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_03",
767
                "settings": {}
768 769 770 771 772
            }
        ]
    }


773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
class MsgAgentConfigured(Message):
    """
    Requirements: Testing Tool SHOULD publish event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description: The goal is to notify GUI when agents are ready to start the session
    """

    routing_key = "control.session"

    _msg_data_template = {
        "_type": "agent.configured",
        "description": "Event agent successfully CONFIGURED",
        'name': 'agent_TT'
    }


793 794
class MsgTestingToolConfigured(Message):
    """
795
    Requirements: TT MUST publish event once session.configuration message has been processed.
Federico Sismondi's avatar
Federico Sismondi committed
796

797
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
798

799
    Pub/Sub: Testing Tool -> Orchestrator, GUI
Federico Sismondi's avatar
Federico Sismondi committed
800

801
    Description: The goal is to notify orchestrator and other components that the testing tool has been configured
802 803 804 805 806
    """

    routing_key = "control.session"

    _msg_data_template = {
807 808 809
        "_type": "testingtool.configured",
        "description": "Event Testing tool CONFIGURED",
        "session_id": "TBD",
810 811 812
        "testing_tools": "f-interop/interoperability-coap",
    }

813

814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
class MsgSessionCreated(Message):
    """
    Requirements: Session Orchestrator MUST publish message on common-services channel (on every session creation)

    Type: Event

    Pub/Sub: SO -> viz tools

    Description: The goal is to notify viz tools about new sessions
    """

    routing_key = "control.session.created"

    _msg_data_template = {
        "_type": "session.created",
        "description": "A new session has been created",
        "session_id": "TBD",
        "testing_tools": "TBD",
    }


835 836
class MsgTestingToolComponentShutdown(Message):
    """
837
    Requirements: Testing Tool SHOULD implement (other components should not subscribe to event)
Federico Sismondi's avatar
Federico Sismondi committed
838

839
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
840

841
    Pub/Sub: Any Testing tool's component -> Test Coordinator
Federico Sismondi's avatar
Federico Sismondi committed
842

843 844
    Description: tbd
    """
845 846 847
    routing_key = "control.session"

    _msg_data_template = {
848
        "_type": "testingtool.component.shutdown",
849
        "component": "SomeComponent",
850
        "description": "Event Component SHUTDOWN. Bye!"
851 852
    }

853
    # # # # # # TEST COORDINATION MESSAGES # # # # # #
854

855 856 857

class MsgTestSuiteStart(Message):
    """
858
    Requirements: TT MUST listen to event and start the test suite right after reception. MsgTestSuiteStarted
Federico Sismondi's avatar
Federico Sismondi committed
859

860
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
861

862
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
863

864
    Description: tbd
865 866
    """

867
    # TODO change to control.testsuite
868
    routing_key = "control.testcoordination"
869 870

    _msg_data_template = {
871
        "_type": "testcoordination.testsuite.start",
872
        "description": "Event test suite START"
873 874
    }

875

Federico Sismondi's avatar
Federico Sismondi committed
876 877 878 879 880 881 882 883 884 885 886
class MsgTestSuiteStarted(Message):
    """
    Requirements: Testing Tool SHOULD publish to event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description: tbd
    """

887
    # TODO change to control.testsuite
Federico Sismondi's avatar
Federico Sismondi committed
888 889 890 891 892 893
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.testsuite.started",
        "description": "Event test suite STARTED"
    }
894

895

896 897
class MsgTestSuiteFinish(Message):
    """
898
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
899

900
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
901

902
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
903

904
    Description: tbd
905 906
    """

907
    # TODO change to control.testsuite
908 909 910
    routing_key = "control.testcoordination"

    _msg_data_template = {
911
        "_type": "testcoordination.testsuite.finish",
912
        "description": "Event test suite FINISH"
913 914
    }

915

916 917
class MsgTestCaseReady(Message):
    """
918
    Requirements: TT MUST publish event
Federico Sismondi's avatar
Federico Sismondi committed
919

920
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
921

Federico Sismondi's avatar
Federico Sismondi committed
922
    Pub/Sub: Testing Tool -> GUI
Federico Sismondi's avatar
Federico Sismondi committed
923

924 925 926
    Description:
        - Used to indicate to the GUI (or automated-iut) which is the next test case to be executed.
        - This message is normally followed by a MsgTestCaseStart (from GUI-> Testing Tool)
927 928
    """

929
    # TODO change to control.testsuite
930
    routing_key = "control.testcoordination"
931 932

    _msg_data_template = {
933
        "_type": "testcoordination.testcase.ready",
Federico Sismondi's avatar
Federico Sismondi committed
934 935 936
        "description": "Next test case to be executed is TD_COAP_CORE_01",
        "testcase_id": "TD_COAP_CORE_01",
        "testcase_ref": "http://doc.f-interop.eu/tests/TD_COAP_CORE_01",
937 938
        "objective": "Perform GET transaction(CON mode)",
        "state": None
939 940 941
    }


942 943
class MsgTestCaseStart(Message):
    """
944
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
945

946
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
947

948
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
949

950 951
    Description:
        - Message used for indicating the testing tool to start the test case (the one previously selected)
952 953
        - if testcase_id is Null then testing tool starts previously announced testcase in message
        "testcoordination.testcase.ready",
954
    """
955
    # TODO change to control.testsuite
956
    routing_key = "control.testcoordination"
957 958

    _msg_data_template = {
959
        "_type": "testcoordination.testcase.start",
960 961
        "description": "Event test case START",
        "testcase_id": "TBD",
962 963
    }

Federico Sismondi's avatar
Federico Sismondi committed
964

965 966 967 968 969 970 971 972 973 974 975
class MsgTestCaseStarted(Message):
    """
    Requirements: Testing Tool SHOULD publish event

    Type: Event

    Pub/Sub: Testing Tool -> GUI

    Description:
        - Message used for indicating that testcase has started
    """
976
    # TODO change to control.testsuite
977 978 979 980 981 982 983
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.testcase.started",
        "description": "Event test case STARTED",
        "testcase_id": "TBD",
    }
984

Federico Sismondi's avatar
Federico Sismondi committed
985

986 987
# TODO MsgTestCaseNotes, see https://portal.etsi.org/cti/downloads/TestSpecifications/6LoWPAN_Plugtests_TestDescriptions_1.0.pdf

988

989 990
class MsgTestCaseConfiguration(Message):
    """
991
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
992 993 994 995 996 997
    Type: Event
    Pub/Sub: Testing Tool -> GUI & automated-iut
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
        - IMPORTANT: deprecate this message in favor of MsgConfigurationExecute and MsgConfigurationExecuted
    """
998 999

    # TODO change to control.testsuite
1000 1001 1002
    routing_key = "control.testcoordination"
    _msg_data_template = {
        "_type": "testcoordination.testcase.configuration",
Federico Sismondi's avatar
Federico Sismondi committed
1003
        "configuration_id": "COAP_CFG_01",
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
        "node": "coap_server",
        "testcase_id": "TBD",
        "testcase_ref": "TBD",
        "description":
            ["CoAP servers running service at [bbbb::2]:5683",
             "CoAP servers are requested to offer the following resources",
             ["/test", "Default test resource", "Should not exceed 64bytes"],
             ["/seg1/seg2/seg3", "Long path ressource", "Should not exceed 64bytes"],
             ["/query", "Ressource accepting query parameters", "Should not exceed 64bytes"],
             ["/separate",
              "Ressource which cannot be served immediately and which cannot be "
              "acknowledged in a piggy-backed way",
              "Should not exceed 64bytes"],
             ["/large", "Large resource (>1024 bytes)", "shall not exceed 2048bytes"],
             ["/large_update",
              "Large resource that can be updated using PUT method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/large_create",
              "Large resource that can be  created using POST method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/obs", "Observable resource which changes every 5 seconds",
              "shall not exceed 2048bytes"],
             ["/.well-known/core", "CoRE Link Format", "may require usage of Block options"]
             ]
    }


class MsgConfigurationExecute(Message):
    """
    Requirements: Testing Tool MAY publish event (if needed for executing the test case)
Federico Sismondi's avatar
Federico Sismondi committed
1034

1035
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1036

1037
    Pub/Sub: Testing Tool -> GUI & automated-iut
Federico Sismondi's avatar
Federico Sismondi committed
1038

1039 1040
    Description:
        - Message used to indicate GUI and/or automated-iut which configuration to use.
1041
    """
1042 1043

    # TODO change to control.testsuite
1044 1045 1046
    routing_key = "control.testcoordination"

    _msg_data_template = {
1047
        "_type": "testcoordination.configuration.execute",
Federico Sismondi's avatar
Federico Sismondi committed
1048
        "configuration_id": "COAP_CFG_01",
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
        "node": "coap_server",
        "testcase_id": "TBD",
        "testcase_ref": "TBD",
        "description":
            ["CoAP servers running service at [bbbb::2]:5683",
             "CoAP servers are requested to offer the following resources",
             ["/test", "Default test resource", "Should not exceed 64bytes"],
             ["/seg1/seg2/seg3", "Long path ressource", "Should not exceed 64bytes"],
             ["/query", "Ressource accepting query parameters", "Should not exceed 64bytes"],
             ["/separate",
              "Ressource which cannot be served immediately and which cannot be "
              "acknowledged in a piggy-backed way",
              "Should not exceed 64bytes"],
             ["/large", "Large resource (>1024 bytes)", "shall not exceed 2048bytes"],
             ["/large_update",
              "Large resource that can be updated using PUT method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/large_create",
              "Large resource that can be  created using POST method (>1024 bytes)",
              "shall not exceed 2048bytes"],
             ["/obs", "Observable resource which changes every 5 seconds",
              "shall not exceed 2048bytes"],
             ["/.well-known/core", "CoRE Link Format", "may require usage of Block options"]
             ]
1073 1074 1075
    }


1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
class MsgConfigurationExecuted(Message):
    """
    Requirements: Testing Tool SHOULD listen to event

    Type: Event

    Pub/Sub: GUI (automated-IUT) -> Testing Tool

    Description:
        - Message used for indicating that the IUT has been configured as requested
1086
        - pixit must be included in this message (pixit = Protocol Implementaiton eXtra Information for Testing)
1087
    """
1088 1089

    # TODO change to control.testsuite
1090 1091 1092 1093 1094
    routing_key = "control.testcoordination"

    _msg_data_template = {
        "_type": "testcoordination.configuration.executed",
        "description": "Event IUT has been configured",
1095
        "node": "coap_server",
Federico Sismondi's avatar
Federico Sismondi committed
1096
        "ipv6_address": "tbd"  # example of pixit
1097 1098 1099
    }


1100 1101
class MsgTestCaseStop(Message):
    """
1102
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1103

1104
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1105

1106
    Pub/Sub: GUI & automated-iut -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1107

1108 1109
    Description:
        - Message used for indicating the testing tool to stop the test case (the one running).
1110 1111
    """

1112
    # TODO change to control.testsuite
1113
    routing_key = "control.testcoordination"
1114 1115

    _msg_data_template = {
1116
        "_type": "testcoordination.testcase.stop",
1117
        "description": "Event test case STOP"
1118 1119 1120 1121 1122
    }


class MsgTestCaseRestart(Message):
    """
1123
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1124

1125
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1126

1127
    Pub/Sub: GUI -> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1128

1129
    Description: Restart the running test cases.
1130 1131
    """

1132
    # TODO change to control.testsuite
1133
    routing_key = "control.testcoordination"
1134 1135

    _msg_data_template = {
1136
        "_type": "testcoordination.testcase.restart",
1137
        "description": "Event test case RESTART"
1138 1139
    }

1140

1141
class MsgStepStimuliExecute(Message):
1142
    """
1143
    Requirements: TT MUST publish event
1144

1145
    Type: Event
1146

1147
    Pub/Sub: Testing Tool -> GUI
1148

1149
    Description:
1150 1151
        - Used to indicate to the GUI (or automated-iut) which is the stimuli step to be executed by the user (or
        automated-IUT).
1152 1153
    """

1154
    # TODO change to control.testsuite
1155
    routing_key = "control.testcoordination"
1156 1157

    _msg_data_template = {
1158
        "_type": "testcoordination.step.stimuli.execute",
Federico Sismondi's avatar
Federico Sismondi committed
1159 1160
        "description": "Please execute TD_COAP_CORE_01_step_01",
        "step_id": "TD_COAP_CORE_01_step_01",
1161 1162
        "step_type": "stimuli",
        "step_info": [
1163 1164 1165 1166
            "Client is requested to send a GET request with",
            "Type = 0(CON)",
            "Code = 1(GET)"
        ],
1167 1168
        "step_state": "executing",
        "node": "coap_client",
1169
        "node_execution_mode": "user_assisted",
1170
        "testcase_id": "TBD",
Federico Sismondi's avatar
Federico Sismondi committed
1171 1172
        "testcase_ref": "TBD",
        "target_address": "TBD"
1173 1174
    }

1175

1176
class MsgStepStimuliExecuted(Message):
1177
    """
1178
    Requirements: TT MUST listen to event
Federico Sismondi's avatar
Federico Sismondi committed
1179

1180
    Type: Event
Federico Sismondi's avatar
Federico Sismondi committed
1181

1182
    Pub/Sub: GUI (or automated-IUT)-> Testing Tool
Federico Sismondi's avatar
Federico Sismondi committed
1183

1184 1185
    Description:
        - Used to indicate stimuli has been executed by user (and it's user-assisted iut) or by automated-iut
1186 1187
    """

1188
    # TODO change to control.testsuite
1189
    routing_key = "control.testcoordination"
1190 1191

    _msg_data_template = {
1192
        "_type": "testcoordination.step.stimuli.executed",
1193 1194 1195
        "description": "Event step (stimuli) EXECUTED",
        "node": "coap_client",
        "node_execution_mode": "user_assisted",
1196 1197 1198
    }


1199
class MsgStepCheckExecute(Message):