From 937bb12727f42dbef7dd7e3702492c12ca1d1009 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Mon, 27 Sep 2021 16:18:53 +0300 Subject: [PATCH 01/18] Create EnvironmentService class. Move exceptions file from auth to environments module --- auth/auth.py | 14 ++------------ environments/environmental_services.py | 15 +++++++++++++++ environments/exceptions.py | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 environments/environmental_services.py create mode 100644 environments/exceptions.py diff --git a/auth/auth.py b/auth/auth.py index 93576f02..09426157 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -3,27 +3,17 @@ from auth.exceptions import InvalidEnvironmentSetup from auth.parameters import AuthUrlParameter from auth.response import AuthResponse +from environments.environmental_services import EnvironmentalService from environments.environments import ProductionEnvironment, QAEnvironment -class Authorization: +class Authorization(EnvironmentalService): SIGNATURE_KEY = "signature" STATE_KEY = "state" TOKEN_KEY = "token" ERROR_KEY = "error" - def __init__(self, env): - self._set_env(env) - - def _set_env(self, env) -> None: - if env == "QA": - self._environment = QAEnvironment() - elif env == "Production": - self._environment = ProductionEnvironment() - else: - raise InvalidEnvironmentSetup(env=env) - def get_auth_request_url(self, parameters: AuthUrlParameter) -> str: auth_parameters = parameters.get_parameters() return self._environment.get_secured_onboarding_authorization_url(**auth_parameters) diff --git a/environments/environmental_services.py b/environments/environmental_services.py new file mode 100644 index 00000000..5d9da90f --- /dev/null +++ b/environments/environmental_services.py @@ -0,0 +1,15 @@ +from environments.exceptions import InvalidEnvironmentSetup +from environments.environments import ProductionEnvironment, QAEnvironment + + +class EnvironmentalService: + def __init__(self, env): + self._set_env(env) + + def _set_env(self, env) -> None: + if env == "QA": + self._environment = QAEnvironment() + elif env == "Production": + self._environment = ProductionEnvironment() + else: + raise InvalidEnvironmentSetup(env=env) \ No newline at end of file diff --git a/environments/exceptions.py b/environments/exceptions.py new file mode 100644 index 00000000..2ebb7c2a --- /dev/null +++ b/environments/exceptions.py @@ -0,0 +1,16 @@ + + +class InvalidEnvironmentSetup(Exception): + + def __init__(self, message=None, env=None): + if not message: + message = "Invalid value of env parameter. [QA] or [Production] values are allowed" + self.message = message + self.env = env + + +class BadAuthResponse(Exception): + def __init__(self, message=None): + if not message: + message = "Bad Response. Response could is not verified." + self.message = message From 95d608324531389184e5ef473a5b644a6a94f226 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Mon, 27 Sep 2021 16:31:04 +0300 Subject: [PATCH 02/18] Fix exceptions in auth --- auth/auth.py | 2 -- auth/exceptions.py | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/auth/auth.py b/auth/auth.py index 09426157..6d23e662 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -1,10 +1,8 @@ from urllib.parse import urlparse, parse_qs -from auth.exceptions import InvalidEnvironmentSetup from auth.parameters import AuthUrlParameter from auth.response import AuthResponse from environments.environmental_services import EnvironmentalService -from environments.environments import ProductionEnvironment, QAEnvironment class Authorization(EnvironmentalService): diff --git a/auth/exceptions.py b/auth/exceptions.py index 2ebb7c2a..106f9c20 100644 --- a/auth/exceptions.py +++ b/auth/exceptions.py @@ -1,14 +1,4 @@ - -class InvalidEnvironmentSetup(Exception): - - def __init__(self, message=None, env=None): - if not message: - message = "Invalid value of env parameter. [QA] or [Production] values are allowed" - self.message = message - self.env = env - - class BadAuthResponse(Exception): def __init__(self, message=None): if not message: From cb6191b67760cead432a65313a2977d7fa6d1210 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Mon, 27 Sep 2021 16:31:36 +0300 Subject: [PATCH 03/18] Change message of InvalidEnvironmentSetup --- environments/exceptions.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/environments/exceptions.py b/environments/exceptions.py index 2ebb7c2a..6430b632 100644 --- a/environments/exceptions.py +++ b/environments/exceptions.py @@ -4,13 +4,8 @@ class InvalidEnvironmentSetup(Exception): def __init__(self, message=None, env=None): if not message: - message = "Invalid value of env parameter. [QA] or [Production] values are allowed" - self.message = message - self.env = env - + message = "Invalid value of env parameter. [QA] or [Production] values are allowed. " \ + "Please use environments.enums.Enviroments enum for configure environment properly" -class BadAuthResponse(Exception): - def __init__(self, message=None): - if not message: - message = "Bad Response. Response could is not verified." self.message = message + self.env = env From c0569f043384c694715c38cf8364c69ea907e850 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 11:01:08 +0300 Subject: [PATCH 04/18] Implement Onboarding --- constants/__init__.py | 0 constants/keys.py | 0 constants/media_types.py | 5 ++ environments/enums.py | 0 environments/environmental_services.py | 2 +- onboarding/__init__.py | 0 onboarding/enums.py | 11 +++ onboarding/exceptions.py | 15 ++++ onboarding/headers.py | 48 ++++++++++++ onboarding/onboarding.py | 70 +++++++++++++++++ onboarding/parameters.py | 95 +++++++++++++++++++++++ onboarding/request.py | 53 +++++++++++++ onboarding/request_body.py | 101 +++++++++++++++++++++++++ onboarding/response.py | 29 +++++++ onboarding/signature.py | 29 +++++++ revoking/__init__.py | 0 revoking/headers.py | 23 ++++++ revoking/parameters.py | 34 +++++++++ revoking/request.py | 36 +++++++++ revoking/request_body.py | 30 ++++++++ revoking/response.py | 7 ++ revoking/revoking.py | 30 ++++++++ 22 files changed, 617 insertions(+), 1 deletion(-) create mode 100644 constants/__init__.py create mode 100644 constants/keys.py create mode 100644 constants/media_types.py create mode 100644 environments/enums.py create mode 100644 onboarding/__init__.py create mode 100644 onboarding/enums.py create mode 100644 onboarding/exceptions.py create mode 100644 onboarding/headers.py create mode 100644 onboarding/onboarding.py create mode 100644 onboarding/parameters.py create mode 100644 onboarding/request.py create mode 100644 onboarding/request_body.py create mode 100644 onboarding/response.py create mode 100644 onboarding/signature.py create mode 100644 revoking/__init__.py create mode 100644 revoking/headers.py create mode 100644 revoking/parameters.py create mode 100644 revoking/request.py create mode 100644 revoking/request_body.py create mode 100644 revoking/response.py create mode 100644 revoking/revoking.py diff --git a/constants/__init__.py b/constants/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/constants/keys.py b/constants/keys.py new file mode 100644 index 00000000..e69de29b diff --git a/constants/media_types.py b/constants/media_types.py new file mode 100644 index 00000000..a77638f6 --- /dev/null +++ b/constants/media_types.py @@ -0,0 +1,5 @@ +from auth.enums import BaseEnum + + +class ContentTypes(BaseEnum): + APPLICATION_JSON = "application/json" diff --git a/environments/enums.py b/environments/enums.py new file mode 100644 index 00000000..e69de29b diff --git a/environments/environmental_services.py b/environments/environmental_services.py index 5d9da90f..f980cd2f 100644 --- a/environments/environmental_services.py +++ b/environments/environmental_services.py @@ -12,4 +12,4 @@ def _set_env(self, env) -> None: elif env == "Production": self._environment = ProductionEnvironment() else: - raise InvalidEnvironmentSetup(env=env) \ No newline at end of file + raise InvalidEnvironmentSetup(env=env) diff --git a/onboarding/__init__.py b/onboarding/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/onboarding/enums.py b/onboarding/enums.py new file mode 100644 index 00000000..cc7dbd31 --- /dev/null +++ b/onboarding/enums.py @@ -0,0 +1,11 @@ +from auth.enums import BaseEnum + + +class CertificateTypes(BaseEnum): + PEM = "PEM" + P12 = "P12" + + +class GateWays(BaseEnum): + MQTT = "2" + REST = "3" diff --git a/onboarding/exceptions.py b/onboarding/exceptions.py new file mode 100644 index 00000000..96686763 --- /dev/null +++ b/onboarding/exceptions.py @@ -0,0 +1,15 @@ +class AgriRouuterBaseException(Exception): + _message = ... + + def __init__(self, message=None): + if not message: + message = self._message + self.message = message + + +class WrongCertificationType(AgriRouuterBaseException): + _message = "Wrong Certification type. Use onboarding.enums.CertificationTypes values instead." + + +class WrongGateWay(AgriRouuterBaseException): + _message = "Wrong Gate Way Id. Use onboarding.enums.GateWays values instead." diff --git a/onboarding/headers.py b/onboarding/headers.py new file mode 100644 index 00000000..32b17a56 --- /dev/null +++ b/onboarding/headers.py @@ -0,0 +1,48 @@ +from abc import ABC, abstractmethod + +from constants.media_types import ContentTypes + + +class BaseOnboardingHeader(ABC): + @abstractmethod + def __init__(self, *args, **kwargs): + self._set_params(*args, **kwargs) + + @abstractmethod + def get_header(self) -> dict: + ... + + @abstractmethod + def _set_params(self, *args, **kwargs): + ... + + +class SoftwareOnboardingHeader(BaseOnboardingHeader): + def __init__(self, + reg_code, + application_id, + signature=None, + content_type=ContentTypes.APPLICATION_JSON.value + ): + + self._set_params(reg_code, application_id, signature, content_type) + + def get_header(self) -> dict: + return self.params + + def sign(self, signature): + self.params["X-Agrirouter-Signature"] = signature + + def _set_params(self, reg_code: str, application_id: str, signature: str, content_type: str): + header = dict() + header["Authorization"] = f"Bearer {reg_code}" + header["Content-Type"] = content_type + header["X-Agrirouter-ApplicationId"] = application_id + if signature: + header["X-Agrirouter-Signature"] = signature + + self.params = header + + +class CUOnboardingHeader(BaseOnboardingHeader): + pass diff --git a/onboarding/onboarding.py b/onboarding/onboarding.py new file mode 100644 index 00000000..28071c54 --- /dev/null +++ b/onboarding/onboarding.py @@ -0,0 +1,70 @@ +import requests + +from environments.environmental_services import EnvironmentalService +from onboarding.headers import SoftwareOnboardingHeader, CUOnboardingHeader +from onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, RevokingParameter, \ + CUOnboardingParameter +from onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest +from onboarding.request_body import SoftwareOnboardingBody, CUOnboardingBody +from onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, RevokingResponse, \ + CUOnboardingResponse + + +class SoftwareOnboarding(EnvironmentalService): + + def _create_request(self, params: BaseOnboardingParameter, url: str) -> SoftwareOnboardingRequest: + body_params = params.get_body_params() + request_body = SoftwareOnboardingBody(**body_params) + + header_params = params.get_header_params() + header_params["request_body"] = request_body.json(new_lines=False) + request_header = SoftwareOnboardingHeader(**header_params) + + return SoftwareOnboardingRequest(header=request_header, body=request_body, url=url) + + def _perform_request(self, params: BaseOnboardingParameter, url: str) -> requests.Response: + request = self._create_request(params, url) + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + + def verify(self, params: SoftwareOnboardingParameter) -> SoftwareOnboardingResponse: + url = self._environment.get_verify_onboard_request_url() + http_response = self._perform_request(params=params, url=url) + + return SoftwareOnboardingResponse(http_response) + + def onboard(self, params: SoftwareOnboardingParameter) -> SoftwareOnboardingResponse: + url = self._environment.get_secured_onboard_url() + http_response = self._perform_request(params=params, url=url) + + return SoftwareOnboardingResponse(http_response) + + +class CUOnboarding(EnvironmentalService): + + def _create_request(self, params: CUOnboardingParameter, url: str) -> CUOnboardingRequest: + body_params = params.get_body_params() + request_body = CUOnboardingBody(**body_params) + + header_params = params.get_header_params() + header_params["request_body"] = request_body.json(new_lines=False) + request_header = CUOnboardingHeader(**header_params) + + return CUOnboardingRequest(header=request_header, body=request_body, url=url) + + def _perform_request(self, params: CUOnboardingParameter, url: str) -> requests.Response: + request = self._create_request(params, url) + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + + def onboard(self, params: CUOnboardingParameter) -> CUOnboardingResponse: + url = self._environment.get_onboard_url() + http_response = self._perform_request(params=params, url=url) + + return CUOnboardingResponse(http_response) diff --git a/onboarding/parameters.py b/onboarding/parameters.py new file mode 100644 index 00000000..b8a4f879 --- /dev/null +++ b/onboarding/parameters.py @@ -0,0 +1,95 @@ +from abc import ABC, abstractmethod + +from constants.media_types import ContentTypes +from onboarding.enums import CertificateTypes + + +class BaseOnboardingParameter(ABC): + @abstractmethod + def __init__(self, *args, **kwargs): + ... + + @abstractmethod + def get_header_params(self, *args, **kwargs): + ... + + @abstractmethod + def get_body_params(self, *args, **kwargs): + ... + + +class SoftwareOnboardingParameter(BaseOnboardingParameter): + def __init__(self, + id_, + application_id, + certification_version_id, + gateway_id, + utc_timestamp, + time_zone, + reg_code, + content_type=ContentTypes.APPLICATION_JSON.value, + certificate_type=CertificateTypes.P12.value, + ): + + self.id_ = id_ + self.application_id = application_id + self.content_type = content_type + self.certification_version_id = certification_version_id + self.gateway_id = gateway_id + self.certificate_type = certificate_type + self.utc_timestamp = utc_timestamp + self.time_zone = time_zone + self.reg_code = reg_code + + def get_header_params(self): + return { + "content_type": self.content_type, + "reg_code": self.reg_code, + "application_id": self.application_id, + } + + def get_body_params(self): + return { + "id": self.id_, + "application_id": self.application_id, + "certification_version_id": self.certification_version_id, + "gateway_id": self.gateway_id, + "certificate_type": self.certificate_type, + "utc_timestamp": self.utc_timestamp, + "time_zone": self.time_zone, + } + + +class CUOnboardingParameter(BaseOnboardingParameter): + def __init__(self, + id_, + application_id, + certification_version_id, + gateway_id, + reg_code, + content_type=ContentTypes.APPLICATION_JSON.value, + certificate_type=CertificateTypes.P12.value, + ): + + self.id_ = id_ + self.application_id = application_id + self.content_type = content_type + self.certification_version_id = certification_version_id + self.gateway_id = gateway_id + self.certificate_type = certificate_type + self.reg_code = reg_code + + def get_header_params(self): + return { + "content_type": self.content_type, + "reg_code": self.reg_code, + } + + def get_body_params(self): + return { + "id": self.id_, + "application_id": self.application_id, + "certification_version_id": self.certification_version_id, + "gateway_id": self.gateway_id, + "certificate_type": self.certificate_type, + } diff --git a/onboarding/request.py b/onboarding/request.py new file mode 100644 index 00000000..5dda15b5 --- /dev/null +++ b/onboarding/request.py @@ -0,0 +1,53 @@ +from onboarding.headers import SoftwareOnboardingHeader, BaseOnboardingHeader +from onboarding.request_body import SoftwareOnboardingBody, BaseOnboardingBody + + +class BaseOnboardingRequest: + def __init__(self, header: BaseOnboardingHeader, body: BaseOnboardingBody, url: str): + self.header = header + self.body = body + self.url = url + + def get_url(self): + return self.url + + def get_data(self): + return self.body.get_parameters() + + def get_header(self): + return self.header.get_header() + + def sign(self): + """ + TODO: add here create_signature + :return: + """ + signature = ... # create signature + self.header.sign(signature) + pass + + @property + def is_signed(self): + header_has_signature = self.get_header().get("X-Agrirouter-Signature", None) + if header_has_signature: + return True + return False + + @property + def is_valid(self): + if not self.is_signed: + return False + + +class SoftwareOnboardingRequest(BaseOnboardingRequest): + """ + Request must be used to onboard Farming Software or Telemetry Platform + """ + pass + + +class CUOnboardingRequest(BaseOnboardingRequest): + """ + Request must be used to onboard CUs + """ + pass diff --git a/onboarding/request_body.py b/onboarding/request_body.py new file mode 100644 index 00000000..b4f922b6 --- /dev/null +++ b/onboarding/request_body.py @@ -0,0 +1,101 @@ +import json +from abc import ABC, abstractmethod + +from onboarding.enums import CertificateTypes, GateWays +from onboarding.exceptions import WrongCertificationType, WrongGateWay + + +class BaseOnboardingBody(ABC): + @abstractmethod + def __init__(self, *args, **kwargs): + ... + + @abstractmethod + def get_parameters(self, *args, **kwargs) -> dict: + ... + + @abstractmethod + def _set_params(self, *args, **kwargs): + ... + + +class SoftwareOnboardingBody(BaseOnboardingBody): + def __init__(self, + id_, + application_id, + certification_version_id, + gateway_id, + certificate_type, + utc_timestamp, + time_zone + ): + + self._validate_certificate_type(certificate_type) + self._validate_gateway_id(gateway_id) + + self._set_params( + id_, + application_id, + certification_version_id, + gateway_id, + certificate_type, + utc_timestamp, + time_zone + ) + + def get_parameters(self) -> dict: + return self.params + + def _set_params(self, + id_, + application_id, + certification_version_id, + gateway_id, + certificate_type, + utc_timestamp, + time_zone + ): + + self.params = { + "id": id_, + "applicationId": application_id, + "certificationVersionId": certification_version_id, + "gatewayId": gateway_id, + "certificateType": certificate_type, + "UTCTimestamp": utc_timestamp, + "timeZone": time_zone, + } + + def json(self, new_lines: bool = True) -> str: + result = json.dumps(self.get_parameters(), indent="") + if not new_lines: + return result.replace("\n", "") + return result + + @staticmethod + def _validate_certificate_type(certificate_type: str) -> None: + if certificate_type not in CertificateTypes.values_list(): + raise WrongCertificationType + + @staticmethod + def _validate_gateway_id(gateway_id: str) -> None: + if gateway_id not in GateWays.values_list(): + raise WrongGateWay + + +class CUOnboardingBody(BaseOnboardingBody): + + def __init__(self, *args, **kwargs): + ... + + def get_parameters(self, *args, **kwargs) -> dict: + ... + + def _set_params(self, *args, **kwargs): + ... + + def json(self, new_lines: bool = True) -> str: + result = json.dumps(self.get_parameters(), indent="") + if not new_lines: + return result.replace("\n", "") + return result diff --git a/onboarding/response.py b/onboarding/response.py new file mode 100644 index 00000000..e1d1d420 --- /dev/null +++ b/onboarding/response.py @@ -0,0 +1,29 @@ +from abc import ABC, abstractmethod + + +class BaseOnboardingResonse(ABC): + @abstractmethod + def __init__(self, http_response): + self.response = http_response + + +class SoftwareVerifyOnboardingResponse(BaseOnboardingResonse): + """ + Response from verify request used for Farming Software or Telemetry Platform before onboarding + """ + pass + + +class SoftwareOnboardingResponse(BaseOnboardingResonse): + """ + Response from onboarding request used for Farming Software or Telemetry Platform + """ + pass + + +class CUOnboardingResponse(BaseOnboardingResonse): + """ + Response from onboarding request used for CUs + """ + pass + diff --git a/onboarding/signature.py b/onboarding/signature.py new file mode 100644 index 00000000..fa68befc --- /dev/null +++ b/onboarding/signature.py @@ -0,0 +1,29 @@ +from cryptography.hazmat.primitives.serialization import load_pem_public_key, load_pem_private_key +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding + +from pprint import pprint + +SIGNATURE_ALGORITHM = "SHA256withRSA" + + +def create_signature(request_body: str, private_key: str) -> bytes: + private_key_bytes = bytearray(private_key.encode('utf-8')) + private_key_data = load_pem_private_key(private_key_bytes, None) + signature = private_key_data.sign( + request_body.encode('utf-8'), + padding.PKCS1v15(), + hashes.SHA256() + ) + return signature + + +def verify_signature(request_body: str, signature: bytearray, public_key: str) -> None: + public_key_bytes = bytearray(public_key.encode('utf-8')) + public_key_data = load_pem_public_key(public_key_bytes) + public_key_data.verify( + signature, + request_body.encode('utf-8'), + padding.PKCS1v15(), + hashes.SHA256() + ) diff --git a/revoking/__init__.py b/revoking/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/revoking/headers.py b/revoking/headers.py new file mode 100644 index 00000000..c4d1b7a8 --- /dev/null +++ b/revoking/headers.py @@ -0,0 +1,23 @@ +from constants.media_types import ContentTypes + + +class RevokingHeader: + def __init__(self, + application_id, + signature=None, + content_type=ContentTypes.APPLICATION_JSON.value + ): + + self._set_params(application_id, signature, content_type) + + def get_header(self) -> dict: + return self.params + + def _set_params(self, application_id: str, signature: str, content_type: str): + header = dict() + header["Content-Type"] = content_type + header["X-Agrirouter-ApplicationId"] = application_id + if signature: + header["X-Agrirouter-Signature"] = signature + + self.params = header \ No newline at end of file diff --git a/revoking/parameters.py b/revoking/parameters.py new file mode 100644 index 00000000..ef65d556 --- /dev/null +++ b/revoking/parameters.py @@ -0,0 +1,34 @@ +from constants.media_types import ContentTypes + + +class RevokingParameter: + + def __init__(self, + application_id, + account_id, + endpoint_ids, + utc_timestamp, + timestamp, + content_type=ContentTypes.APPLICATION_JSON.value + ): + + self.application_id = application_id + self.content_type = content_type + self.account_id = account_id + self.endpoint_ids = endpoint_ids + self.utc_timestamp = utc_timestamp + self.timestamp = timestamp + + def get_header_params(self): + return { + "application_id": self.application_id, + "content_type": self.content_type, + } + + def get_body_params(self): + return { + "account_id": self.account_id, + "endpoint_ids": self.endpoint_ids, + "utc_timestamp": self.utc_timestamp, + "timestamp": self.timestamp, + } diff --git a/revoking/request.py b/revoking/request.py new file mode 100644 index 00000000..aa7620cc --- /dev/null +++ b/revoking/request.py @@ -0,0 +1,36 @@ +class BaseOnboardingRequest: + def __init__(self, header: RevokingHeader, body: RevokingBody, url: str): + self.header = header + self.body = body + self.url = url + + def get_url(self): + return self.url + + def get_data(self): + return self.body.get_parameters() + + def get_header(self): + return self.header.get_header() + + def sign(self): + """ + TODO: add here create_signature + :return: + """ + signature = ... # create signature + self.header.sign(signature) + + @property + def is_signed(self) -> bool: + header_has_signature = self.get_header().get("X-Agrirouter-Signature", None) + if header_has_signature: + return True + return False + + @property + def is_valid(self) -> bool: + if not self.is_signed: + return False + signature = self.get_header().get("X-Agrirouter-Signature") + # return validate_signature(signature) diff --git a/revoking/request_body.py b/revoking/request_body.py new file mode 100644 index 00000000..e23c2750 --- /dev/null +++ b/revoking/request_body.py @@ -0,0 +1,30 @@ +class RevokingBody: + def __init__(self, + account_id, + endpoint_ids, + utc_timestamp, + time_zone): + + self._set_params( + account_id, + endpoint_ids, + utc_timestamp, + time_zone + ) + + def get_parameters(self) -> dict: + return self.params + + def _set_params(self, + account_id, + endpoint_ids, + utc_timestamp, + time_zone + ) -> None: + + self.params = { + "account_id": account_id, + "endpoint_ids": endpoint_ids, + "UTCTimestamp": utc_timestamp, + "timeZone": time_zone, + } diff --git a/revoking/response.py b/revoking/response.py new file mode 100644 index 00000000..60d0c4bf --- /dev/null +++ b/revoking/response.py @@ -0,0 +1,7 @@ +class RevokingResonse: + """ + Response from revoking request + """ + + def __init__(self, http_response): + self.response = http_response diff --git a/revoking/revoking.py b/revoking/revoking.py new file mode 100644 index 00000000..9d1dc96b --- /dev/null +++ b/revoking/revoking.py @@ -0,0 +1,30 @@ +import requests + +from environments.environmental_services import EnvironmentalService + + +class Revoking(EnvironmentalService): + + def _create_request(self, params: RevokingParameter, url: str) -> RevokingRequest: + body_params = params.get_body_params() + request_body = RevokingBody(**body_params) + + header_params = params.get_header_params() + header_params["request_body"] = request_body.json(new_lines=False) + request_header = RevokingHeader(**header_params) + + return RevokingRequest(header=request_header, body=request_body, url=url) + + def _perform_request(self, params: RevokingParameter, url: str) -> requests.Response: + request = self._create_request(params, url) + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + + def revoke(self, params: RevokingParameter) -> RevokingResponse: + url = self._environment.get_revoke_url() + http_response = self._perform_request(params=params, url=url) + + return RevokingResponse(http_response) \ No newline at end of file From e039b7598930561e79371f993e0fc37a44c172a5 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 12:53:43 +0300 Subject: [PATCH 05/18] Fix import bug in onboarding/onboarding.py --- onboarding/onboarding.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/onboarding/onboarding.py b/onboarding/onboarding.py index 28071c54..24e93d49 100644 --- a/onboarding/onboarding.py +++ b/onboarding/onboarding.py @@ -2,12 +2,10 @@ from environments.environmental_services import EnvironmentalService from onboarding.headers import SoftwareOnboardingHeader, CUOnboardingHeader -from onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, RevokingParameter, \ - CUOnboardingParameter +from onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, CUOnboardingParameter from onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest from onboarding.request_body import SoftwareOnboardingBody, CUOnboardingBody -from onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, RevokingResponse, \ - CUOnboardingResponse +from onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, CUOnboardingResponse class SoftwareOnboarding(EnvironmentalService): From eaaacc4d559486366dbab05976e2cfaa3b6c1505 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 13:14:17 +0300 Subject: [PATCH 06/18] Fix bug in OnboardingParameter.get_body_params() method --- onboarding/parameters.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/onboarding/parameters.py b/onboarding/parameters.py index b8a4f879..12f3373a 100644 --- a/onboarding/parameters.py +++ b/onboarding/parameters.py @@ -35,10 +35,10 @@ def __init__(self, self.application_id = application_id self.content_type = content_type self.certification_version_id = certification_version_id - self.gateway_id = gateway_id + self.gateway_id = str(gateway_id) self.certificate_type = certificate_type - self.utc_timestamp = utc_timestamp - self.time_zone = time_zone + self.utc_timestamp = str(utc_timestamp) + self.time_zone = str(time_zone) self.reg_code = reg_code def get_header_params(self): @@ -50,7 +50,7 @@ def get_header_params(self): def get_body_params(self): return { - "id": self.id_, + "id_": self.id_, "application_id": self.application_id, "certification_version_id": self.certification_version_id, "gateway_id": self.gateway_id, @@ -87,7 +87,7 @@ def get_header_params(self): def get_body_params(self): return { - "id": self.id_, + "id_": self.id_, "application_id": self.application_id, "certification_version_id": self.certification_version_id, "gateway_id": self.gateway_id, From db3f2e0e2dc2b82134f43d7751d56312c730dd97 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 13:15:26 +0300 Subject: [PATCH 07/18] Fix OnboardingParameter.create_request(), OnboardingParameter.create_request() --- onboarding/onboarding.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/onboarding/onboarding.py b/onboarding/onboarding.py index 24e93d49..20365d07 100644 --- a/onboarding/onboarding.py +++ b/onboarding/onboarding.py @@ -15,7 +15,6 @@ def _create_request(self, params: BaseOnboardingParameter, url: str) -> Software request_body = SoftwareOnboardingBody(**body_params) header_params = params.get_header_params() - header_params["request_body"] = request_body.json(new_lines=False) request_header = SoftwareOnboardingHeader(**header_params) return SoftwareOnboardingRequest(header=request_header, body=request_body, url=url) @@ -48,7 +47,6 @@ def _create_request(self, params: CUOnboardingParameter, url: str) -> CUOnboardi request_body = CUOnboardingBody(**body_params) header_params = params.get_header_params() - header_params["request_body"] = request_body.json(new_lines=False) request_header = CUOnboardingHeader(**header_params) return CUOnboardingRequest(header=request_header, body=request_body, url=url) From ad16fc5bd972c77546d7783a3c401eab14438c61 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 13:40:14 +0300 Subject: [PATCH 08/18] Fix revoking --- revoking/headers.py | 3 +++ revoking/request.py | 6 +++++- revoking/response.py | 2 +- revoking/revoking.py | 6 +++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/revoking/headers.py b/revoking/headers.py index c4d1b7a8..08dc878e 100644 --- a/revoking/headers.py +++ b/revoking/headers.py @@ -13,6 +13,9 @@ def __init__(self, def get_header(self) -> dict: return self.params + def sign(self, signatute): + self.params["X-Agrirouter-Signature"] = signatute + def _set_params(self, application_id: str, signature: str, content_type: str): header = dict() header["Content-Type"] = content_type diff --git a/revoking/request.py b/revoking/request.py index aa7620cc..a08898c4 100644 --- a/revoking/request.py +++ b/revoking/request.py @@ -1,4 +1,8 @@ -class BaseOnboardingRequest: +from revoking.headers import RevokingHeader +from revoking.request_body import RevokingBody + + +class RevokingRequest: def __init__(self, header: RevokingHeader, body: RevokingBody, url: str): self.header = header self.body = body diff --git a/revoking/response.py b/revoking/response.py index 60d0c4bf..249cad11 100644 --- a/revoking/response.py +++ b/revoking/response.py @@ -1,4 +1,4 @@ -class RevokingResonse: +class RevokingResponse: """ Response from revoking request """ diff --git a/revoking/revoking.py b/revoking/revoking.py index 9d1dc96b..8a8a4f7b 100644 --- a/revoking/revoking.py +++ b/revoking/revoking.py @@ -1,6 +1,11 @@ import requests from environments.environmental_services import EnvironmentalService +from revoking.headers import RevokingHeader +from revoking.parameters import RevokingParameter +from revoking.request import RevokingRequest +from revoking.request_body import RevokingBody +from revoking.response import RevokingResponse class Revoking(EnvironmentalService): @@ -10,7 +15,6 @@ def _create_request(self, params: RevokingParameter, url: str) -> RevokingReques request_body = RevokingBody(**body_params) header_params = params.get_header_params() - header_params["request_body"] = request_body.json(new_lines=False) request_header = RevokingHeader(**header_params) return RevokingRequest(header=request_header, body=request_body, url=url) From 9372b544c1dded1926f6ccf923107840ff7c7b0e Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 19:34:37 +0300 Subject: [PATCH 09/18] Implement request signing in onboarding --- onboarding/exceptions.py | 6 ++++++ onboarding/headers.py | 4 ++++ onboarding/onboarding.py | 37 +++++++++++++++++++++++++++---------- onboarding/request.py | 15 +++------------ onboarding/request_body.py | 4 ++++ onboarding/response.py | 22 +++++++++++++++++----- onboarding/signature.py | 2 +- 7 files changed, 62 insertions(+), 28 deletions(-) diff --git a/onboarding/exceptions.py b/onboarding/exceptions.py index 96686763..34dc3777 100644 --- a/onboarding/exceptions.py +++ b/onboarding/exceptions.py @@ -13,3 +13,9 @@ class WrongCertificationType(AgriRouuterBaseException): class WrongGateWay(AgriRouuterBaseException): _message = "Wrong Gate Way Id. Use onboarding.enums.GateWays values instead." + + +class RequestNotSigned(AgriRouuterBaseException): + _message = "Request does not contain signature header. Please sign the request with request.sign() method.\n" \ + "Details on: https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/" \ + "integration/onboarding.html#signing-requests" diff --git a/onboarding/headers.py b/onboarding/headers.py index 32b17a56..8ebf313e 100644 --- a/onboarding/headers.py +++ b/onboarding/headers.py @@ -16,6 +16,10 @@ def get_header(self) -> dict: def _set_params(self, *args, **kwargs): ... + @abstractmethod + def sign(self, *args, **kwargs): + ... + class SoftwareOnboardingHeader(BaseOnboardingHeader): def __init__(self, diff --git a/onboarding/onboarding.py b/onboarding/onboarding.py index 20365d07..ee0d3dfe 100644 --- a/onboarding/onboarding.py +++ b/onboarding/onboarding.py @@ -1,6 +1,7 @@ import requests from environments.environmental_services import EnvironmentalService +from onboarding.exceptions import RequestNotSigned from onboarding.headers import SoftwareOnboardingHeader, CUOnboardingHeader from onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, CUOnboardingParameter from onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest @@ -10,6 +11,11 @@ class SoftwareOnboarding(EnvironmentalService): + def __init__(self, *args, **kwargs): + self._public_key = kwargs.pop("public_key") + self._private_key = kwargs.pop("private_key") + super(SoftwareOnboarding, self).__init__(*args, **kwargs) + def _create_request(self, params: BaseOnboardingParameter, url: str) -> SoftwareOnboardingRequest: body_params = params.get_body_params() request_body = SoftwareOnboardingBody(**body_params) @@ -21,11 +27,14 @@ def _create_request(self, params: BaseOnboardingParameter, url: str) -> Software def _perform_request(self, params: BaseOnboardingParameter, url: str) -> requests.Response: request = self._create_request(params, url) - return requests.post( - url=request.get_url(), - data=request.get_data(), - headers=request.get_header() - ) + request.sign(self._private_key) + if request.is_signed: + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + raise RequestNotSigned def verify(self, params: SoftwareOnboardingParameter) -> SoftwareOnboardingResponse: url = self._environment.get_verify_onboard_request_url() @@ -42,6 +51,11 @@ def onboard(self, params: SoftwareOnboardingParameter) -> SoftwareOnboardingResp class CUOnboarding(EnvironmentalService): + def __init__(self, *args, **kwargs): + self._public_key = kwargs.pop("public_key") + self._private_key = kwargs.pop("private_key") + super(CUOnboarding, self).__init__(*args, **kwargs) + def _create_request(self, params: CUOnboardingParameter, url: str) -> CUOnboardingRequest: body_params = params.get_body_params() request_body = CUOnboardingBody(**body_params) @@ -53,11 +67,14 @@ def _create_request(self, params: CUOnboardingParameter, url: str) -> CUOnboardi def _perform_request(self, params: CUOnboardingParameter, url: str) -> requests.Response: request = self._create_request(params, url) - return requests.post( - url=request.get_url(), - data=request.get_data(), - headers=request.get_header() - ) + request.sign(self._private_key) + if request.is_signed: + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + raise RequestNotSigned def onboard(self, params: CUOnboardingParameter) -> CUOnboardingResponse: url = self._environment.get_onboard_url() diff --git a/onboarding/request.py b/onboarding/request.py index 5dda15b5..8ec4258f 100644 --- a/onboarding/request.py +++ b/onboarding/request.py @@ -1,5 +1,6 @@ from onboarding.headers import SoftwareOnboardingHeader, BaseOnboardingHeader from onboarding.request_body import SoftwareOnboardingBody, BaseOnboardingBody +from onboarding.signature import create_signature class BaseOnboardingRequest: @@ -17,14 +18,9 @@ def get_data(self): def get_header(self): return self.header.get_header() - def sign(self): - """ - TODO: add here create_signature - :return: - """ - signature = ... # create signature + def sign(self, private_key): + signature = create_signature(self.body.json(new_lines=False), private_key) self.header.sign(signature) - pass @property def is_signed(self): @@ -33,11 +29,6 @@ def is_signed(self): return True return False - @property - def is_valid(self): - if not self.is_signed: - return False - class SoftwareOnboardingRequest(BaseOnboardingRequest): """ diff --git a/onboarding/request_body.py b/onboarding/request_body.py index b4f922b6..1d6c2ff2 100644 --- a/onboarding/request_body.py +++ b/onboarding/request_body.py @@ -18,6 +18,10 @@ def get_parameters(self, *args, **kwargs) -> dict: def _set_params(self, *args, **kwargs): ... + @abstractmethod + def json(self, *args, **kwargs): + ... + class SoftwareOnboardingBody(BaseOnboardingBody): def __init__(self, diff --git a/onboarding/response.py b/onboarding/response.py index e1d1d420..4718b641 100644 --- a/onboarding/response.py +++ b/onboarding/response.py @@ -1,10 +1,22 @@ -from abc import ABC, abstractmethod +from requests import Response -class BaseOnboardingResonse(ABC): - @abstractmethod - def __init__(self, http_response): - self.response = http_response +class BaseOnboardingResonse: + + def __init__(self, http_response: Response): + self.response: Response = http_response + + @property + def data(self): + return self.response.json() + + @property + def status_code(self): + return self.response.status_code + + @property + def text(self): + return self.response.text class SoftwareVerifyOnboardingResponse(BaseOnboardingResonse): diff --git a/onboarding/signature.py b/onboarding/signature.py index fa68befc..6bedc3bd 100644 --- a/onboarding/signature.py +++ b/onboarding/signature.py @@ -18,7 +18,7 @@ def create_signature(request_body: str, private_key: str) -> bytes: return signature -def verify_signature(request_body: str, signature: bytearray, public_key: str) -> None: +def verify_signature(request_body: str, signature: bytes, public_key: str) -> None: public_key_bytes = bytearray(public_key.encode('utf-8')) public_key_data = load_pem_public_key(public_key_bytes) public_key_data.verify( From 810cb1895384be91db57e85b452abab9f0d9dcf2 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 19:34:52 +0300 Subject: [PATCH 10/18] Implement request signing in revoking --- revoking/request.py | 9 +++------ revoking/request_body.py | 9 +++++++++ revoking/response.py | 19 +++++++++++++++++-- revoking/revoking.py | 19 ++++++++++++++----- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/revoking/request.py b/revoking/request.py index a08898c4..df80233e 100644 --- a/revoking/request.py +++ b/revoking/request.py @@ -1,3 +1,4 @@ +from onboarding.signature import create_signature from revoking.headers import RevokingHeader from revoking.request_body import RevokingBody @@ -17,12 +18,8 @@ def get_data(self): def get_header(self): return self.header.get_header() - def sign(self): - """ - TODO: add here create_signature - :return: - """ - signature = ... # create signature + def sign(self, private_key): + signature = create_signature(self.body.json(new_lines=False), private_key) self.header.sign(signature) @property diff --git a/revoking/request_body.py b/revoking/request_body.py index e23c2750..6ec70b2d 100644 --- a/revoking/request_body.py +++ b/revoking/request_body.py @@ -1,3 +1,6 @@ +import json + + class RevokingBody: def __init__(self, account_id, @@ -28,3 +31,9 @@ def _set_params(self, "UTCTimestamp": utc_timestamp, "timeZone": time_zone, } + + def json(self, new_lines: bool = True) -> str: + result = json.dumps(self.get_parameters(), indent="") + if not new_lines: + return result.replace("\n", "") + return result diff --git a/revoking/response.py b/revoking/response.py index 249cad11..cec8bb00 100644 --- a/revoking/response.py +++ b/revoking/response.py @@ -1,7 +1,22 @@ +from requests import Response + + class RevokingResponse: """ Response from revoking request """ - def __init__(self, http_response): - self.response = http_response + def __init__(self, http_response: Response): + self.response: Response = http_response + + @property + def data(self): + return self.response.json() + + @property + def status_code(self): + return self.response.status_code + + @property + def text(self): + return self.response.text diff --git a/revoking/revoking.py b/revoking/revoking.py index 8a8a4f7b..a1adb219 100644 --- a/revoking/revoking.py +++ b/revoking/revoking.py @@ -1,6 +1,7 @@ import requests from environments.environmental_services import EnvironmentalService +from onboarding.exceptions import RequestNotSigned from revoking.headers import RevokingHeader from revoking.parameters import RevokingParameter from revoking.request import RevokingRequest @@ -10,6 +11,11 @@ class Revoking(EnvironmentalService): + def __init__(self, *args, **kwargs): + self._public_key = kwargs.pop("public_key") + self._private_key = kwargs.pop("private_key") + super(Revoking, self).__init__(*args, **kwargs) + def _create_request(self, params: RevokingParameter, url: str) -> RevokingRequest: body_params = params.get_body_params() request_body = RevokingBody(**body_params) @@ -21,11 +27,14 @@ def _create_request(self, params: RevokingParameter, url: str) -> RevokingReques def _perform_request(self, params: RevokingParameter, url: str) -> requests.Response: request = self._create_request(params, url) - return requests.post( - url=request.get_url(), - data=request.get_data(), - headers=request.get_header() - ) + request.sign(self._private_key) + if request.is_signed: + return requests.post( + url=request.get_url(), + data=request.get_data(), + headers=request.get_header() + ) + raise RequestNotSigned def revoke(self, params: RevokingParameter) -> RevokingResponse: url = self._environment.get_revoke_url() From 0fd281e1c95bc094fba1327df67420991c1893cd Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Tue, 28 Sep 2021 19:35:04 +0300 Subject: [PATCH 11/18] Implement request signing in auth --- auth/auth.py | 10 ++++++++-- auth/response.py | 21 ++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/auth/auth.py b/auth/auth.py index 6d23e662..d0525e82 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -12,6 +12,11 @@ class Authorization(EnvironmentalService): TOKEN_KEY = "token" ERROR_KEY = "error" + def __init__(self, *args, **kwargs): + self._public_key = kwargs.pop("public_key") + self._private_key = kwargs.pop("private_key") + super(Authorization, self).__init__(*args, **kwargs) + def get_auth_request_url(self, parameters: AuthUrlParameter) -> str: auth_parameters = parameters.get_parameters() return self._environment.get_secured_onboarding_authorization_url(**auth_parameters) @@ -21,8 +26,9 @@ def extract_auth_response(self, url: str) -> AuthResponse: query_params = self._extract_query_params(parsed_url.query) return AuthResponse(query_params) - def verify_auth_response(self): - pass + @staticmethod + def verify_auth_response(response, public_key): + response.verify(public_key) @staticmethod def _extract_query_params(query_params: str) -> dict: diff --git a/auth/response.py b/auth/response.py index e67f2b8e..40a6b9c3 100644 --- a/auth/response.py +++ b/auth/response.py @@ -1,6 +1,11 @@ import base64 import json from typing import Union +from urllib.parse import unquote + +from cryptography.exceptions import InvalidSignature + +from onboarding.signature import verify_signature class AuthResponse: @@ -19,7 +24,7 @@ def __init__(self, query_params): self.is_successful = not bool(self._error) self.is_valid = False - def verify(self) -> None: + def verify(self, public_key) -> None: """ Validates signature according to docs: https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/integration/authorization.html#analyse-result @@ -29,17 +34,23 @@ def verify(self) -> None: :return: """ - # TODO: implement validation of response according to docs: - # https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/integration/authorization.html#analyse-result + encoded_data = self._state + self._token + unquoted_signature = unquote(self._signature) + encoded_signature = base64.b64decode(unquoted_signature.encode("utf-8")) + try: + verify_signature(encoded_data, encoded_signature, public_key) + except InvalidSignature: + print("Response is invalid: invalid signature.") + self.is_valid = False self.is_valid = True @staticmethod def decode_token(token: Union[str, bytes]) -> dict: if type(token) == str: - token = token.encode("ASCII") + token = token.encode("utf-8") base_64_decoded_token = base64.b64decode(token) - decoded_token = base_64_decoded_token.decode("ASCII") + decoded_token = base_64_decoded_token.decode("utf-8") return json.loads(decoded_token) def get_auth_result(self) -> dict: From 65f5662dad3564bc4f487b5fd53bcf854571f07c Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Wed, 29 Sep 2021 13:40:28 +0300 Subject: [PATCH 12/18] Refactor RequestNotSigned exception --- onboarding/exceptions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/onboarding/exceptions.py b/onboarding/exceptions.py index 34dc3777..490e51e3 100644 --- a/onboarding/exceptions.py +++ b/onboarding/exceptions.py @@ -16,6 +16,8 @@ class WrongGateWay(AgriRouuterBaseException): class RequestNotSigned(AgriRouuterBaseException): - _message = "Request does not contain signature header. Please sign the request with request.sign() method.\n" \ - "Details on: https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/" \ - "integration/onboarding.html#signing-requests" + _message = """ + Request does not contain signature header. Please sign the request with request.sign() method.\n + Details on: https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/ + integration/onboarding.html#signing-requests + """ From d96a4f3fec53a47f22caf7a198d6ff4543074a34 Mon Sep 17 00:00:00 2001 From: Alexey Petrovsky Date: Wed, 29 Sep 2021 13:53:38 +0300 Subject: [PATCH 13/18] Create requeirements.txt --- requirements.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..e2da2ee2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +certifi==2021.5.30 +cffi==1.14.6 +charset-normalizer==2.0.6 +cryptography==3.4.8 +idna==3.2 +pycparser==2.20 +requests==2.26.0 +urllib3==1.26.7 From bc5cc972df4a2c6622d97267d5fa7975cd33d556 Mon Sep 17 00:00:00 2001 From: kskachkov Date: Mon, 4 Oct 2021 19:08:54 +0300 Subject: [PATCH 14/18] Move files to common agrirouter directory --- {auth => agrirouter/auth}/__init__.py | 0 {auth => agrirouter/auth}/auth.py | 6 +++--- {auth => agrirouter/auth}/enums.py | 0 {auth => agrirouter/auth}/exceptions.py | 0 {auth => agrirouter/auth}/parameters.py | 2 +- {auth => agrirouter/auth}/response.py | 2 +- {clients => agrirouter/clients}/__init__.py | 0 {clients => agrirouter/clients}/clients.py | 2 +- {constants => agrirouter/constants}/__init__.py | 0 {constants => agrirouter/constants}/keys.py | 0 {constants => agrirouter/constants}/media_types.py | 2 +- .../environments}/__init__.py | 0 {environments => agrirouter/environments}/enums.py | 0 .../environments}/environmental_services.py | 4 ++-- .../environments}/environments.py | 0 .../environments}/exceptions.py | 0 {onboarding => agrirouter/onboarding}/__init__.py | 0 {onboarding => agrirouter/onboarding}/enums.py | 2 +- .../onboarding}/exceptions.py | 0 {onboarding => agrirouter/onboarding}/headers.py | 2 +- .../onboarding}/onboarding.py | 14 +++++++------- .../onboarding}/parameters.py | 4 ++-- {onboarding => agrirouter/onboarding}/request.py | 6 +++--- .../onboarding}/request_body.py | 4 ++-- {onboarding => agrirouter/onboarding}/response.py | 0 {onboarding => agrirouter/onboarding}/signature.py | 0 {revoking => agrirouter/revoking}/__init__.py | 0 {revoking => agrirouter/revoking}/headers.py | 2 +- {revoking => agrirouter/revoking}/parameters.py | 2 +- {revoking => agrirouter/revoking}/request.py | 6 +++--- {revoking => agrirouter/revoking}/request_body.py | 0 {revoking => agrirouter/revoking}/response.py | 0 {revoking => agrirouter/revoking}/revoking.py | 14 +++++++------- 33 files changed, 37 insertions(+), 37 deletions(-) rename {auth => agrirouter/auth}/__init__.py (100%) rename {auth => agrirouter/auth}/auth.py (85%) rename {auth => agrirouter/auth}/enums.py (100%) rename {auth => agrirouter/auth}/exceptions.py (100%) rename {auth => agrirouter/auth}/parameters.py (96%) rename {auth => agrirouter/auth}/response.py (97%) rename {clients => agrirouter/clients}/__init__.py (100%) rename {clients => agrirouter/clients}/clients.py (89%) rename {constants => agrirouter/constants}/__init__.py (100%) rename {constants => agrirouter/constants}/keys.py (100%) rename {constants => agrirouter/constants}/media_types.py (63%) rename {environments => agrirouter/environments}/__init__.py (100%) rename {environments => agrirouter/environments}/enums.py (100%) rename {environments => agrirouter/environments}/environmental_services.py (69%) rename {environments => agrirouter/environments}/environments.py (100%) rename {environments => agrirouter/environments}/exceptions.py (100%) rename {onboarding => agrirouter/onboarding}/__init__.py (100%) rename {onboarding => agrirouter/onboarding}/enums.py (74%) rename {onboarding => agrirouter/onboarding}/exceptions.py (100%) rename {onboarding => agrirouter/onboarding}/headers.py (95%) rename {onboarding => agrirouter/onboarding}/onboarding.py (81%) rename {onboarding => agrirouter/onboarding}/parameters.py (96%) rename {onboarding => agrirouter/onboarding}/request.py (80%) rename {onboarding => agrirouter/onboarding}/request_body.py (94%) rename {onboarding => agrirouter/onboarding}/response.py (100%) rename {onboarding => agrirouter/onboarding}/signature.py (100%) rename {revoking => agrirouter/revoking}/__init__.py (100%) rename {revoking => agrirouter/revoking}/headers.py (92%) rename {revoking => agrirouter/revoking}/parameters.py (94%) rename {revoking => agrirouter/revoking}/request.py (84%) rename {revoking => agrirouter/revoking}/request_body.py (100%) rename {revoking => agrirouter/revoking}/response.py (100%) rename {revoking => agrirouter/revoking}/revoking.py (75%) diff --git a/auth/__init__.py b/agrirouter/auth/__init__.py similarity index 100% rename from auth/__init__.py rename to agrirouter/auth/__init__.py diff --git a/auth/auth.py b/agrirouter/auth/auth.py similarity index 85% rename from auth/auth.py rename to agrirouter/auth/auth.py index d0525e82..fa9e2e9a 100644 --- a/auth/auth.py +++ b/agrirouter/auth/auth.py @@ -1,8 +1,8 @@ from urllib.parse import urlparse, parse_qs -from auth.parameters import AuthUrlParameter -from auth.response import AuthResponse -from environments.environmental_services import EnvironmentalService +from agrirouter.auth.parameters import AuthUrlParameter +from agrirouter.auth.response import AuthResponse +from agrirouter.environments.environmental_services import EnvironmentalService class Authorization(EnvironmentalService): diff --git a/auth/enums.py b/agrirouter/auth/enums.py similarity index 100% rename from auth/enums.py rename to agrirouter/auth/enums.py diff --git a/auth/exceptions.py b/agrirouter/auth/exceptions.py similarity index 100% rename from auth/exceptions.py rename to agrirouter/auth/exceptions.py diff --git a/auth/parameters.py b/agrirouter/auth/parameters.py similarity index 96% rename from auth/parameters.py rename to agrirouter/auth/parameters.py index 48ee6e7b..a7d9902d 100644 --- a/auth/parameters.py +++ b/agrirouter/auth/parameters.py @@ -1,6 +1,6 @@ from uuid import uuid4 -from auth.enums import ResponseType +from agrirouter.auth.enums import ResponseType class AuthUrlParameter: diff --git a/auth/response.py b/agrirouter/auth/response.py similarity index 97% rename from auth/response.py rename to agrirouter/auth/response.py index 40a6b9c3..3e4f1067 100644 --- a/auth/response.py +++ b/agrirouter/auth/response.py @@ -5,7 +5,7 @@ from cryptography.exceptions import InvalidSignature -from onboarding.signature import verify_signature +from agrirouter.onboarding.signature import verify_signature class AuthResponse: diff --git a/clients/__init__.py b/agrirouter/clients/__init__.py similarity index 100% rename from clients/__init__.py rename to agrirouter/clients/__init__.py diff --git a/clients/clients.py b/agrirouter/clients/clients.py similarity index 89% rename from clients/clients.py rename to agrirouter/clients/clients.py index f3102e35..f42483ae 100644 --- a/clients/clients.py +++ b/agrirouter/clients/clients.py @@ -1,4 +1,4 @@ -from environments.environments import ProductionEnvironment, QAEnvironment +from agrirouter.environments.environments import ProductionEnvironment, QAEnvironment class InvalidEnvironmentSetup(Exception): diff --git a/constants/__init__.py b/agrirouter/constants/__init__.py similarity index 100% rename from constants/__init__.py rename to agrirouter/constants/__init__.py diff --git a/constants/keys.py b/agrirouter/constants/keys.py similarity index 100% rename from constants/keys.py rename to agrirouter/constants/keys.py diff --git a/constants/media_types.py b/agrirouter/constants/media_types.py similarity index 63% rename from constants/media_types.py rename to agrirouter/constants/media_types.py index a77638f6..56d454f0 100644 --- a/constants/media_types.py +++ b/agrirouter/constants/media_types.py @@ -1,4 +1,4 @@ -from auth.enums import BaseEnum +from agrirouter.auth.enums import BaseEnum class ContentTypes(BaseEnum): diff --git a/environments/__init__.py b/agrirouter/environments/__init__.py similarity index 100% rename from environments/__init__.py rename to agrirouter/environments/__init__.py diff --git a/environments/enums.py b/agrirouter/environments/enums.py similarity index 100% rename from environments/enums.py rename to agrirouter/environments/enums.py diff --git a/environments/environmental_services.py b/agrirouter/environments/environmental_services.py similarity index 69% rename from environments/environmental_services.py rename to agrirouter/environments/environmental_services.py index f980cd2f..c502becd 100644 --- a/environments/environmental_services.py +++ b/agrirouter/environments/environmental_services.py @@ -1,5 +1,5 @@ -from environments.exceptions import InvalidEnvironmentSetup -from environments.environments import ProductionEnvironment, QAEnvironment +from agrirouter.environments.exceptions import InvalidEnvironmentSetup +from agrirouter.environments.environments import ProductionEnvironment, QAEnvironment class EnvironmentalService: diff --git a/environments/environments.py b/agrirouter/environments/environments.py similarity index 100% rename from environments/environments.py rename to agrirouter/environments/environments.py diff --git a/environments/exceptions.py b/agrirouter/environments/exceptions.py similarity index 100% rename from environments/exceptions.py rename to agrirouter/environments/exceptions.py diff --git a/onboarding/__init__.py b/agrirouter/onboarding/__init__.py similarity index 100% rename from onboarding/__init__.py rename to agrirouter/onboarding/__init__.py diff --git a/onboarding/enums.py b/agrirouter/onboarding/enums.py similarity index 74% rename from onboarding/enums.py rename to agrirouter/onboarding/enums.py index cc7dbd31..f25a34e9 100644 --- a/onboarding/enums.py +++ b/agrirouter/onboarding/enums.py @@ -1,4 +1,4 @@ -from auth.enums import BaseEnum +from agrirouter.auth.enums import BaseEnum class CertificateTypes(BaseEnum): diff --git a/onboarding/exceptions.py b/agrirouter/onboarding/exceptions.py similarity index 100% rename from onboarding/exceptions.py rename to agrirouter/onboarding/exceptions.py diff --git a/onboarding/headers.py b/agrirouter/onboarding/headers.py similarity index 95% rename from onboarding/headers.py rename to agrirouter/onboarding/headers.py index 8ebf313e..20fcf6fa 100644 --- a/onboarding/headers.py +++ b/agrirouter/onboarding/headers.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod -from constants.media_types import ContentTypes +from agrirouter.constants.media_types import ContentTypes class BaseOnboardingHeader(ABC): diff --git a/onboarding/onboarding.py b/agrirouter/onboarding/onboarding.py similarity index 81% rename from onboarding/onboarding.py rename to agrirouter/onboarding/onboarding.py index ee0d3dfe..0d0094e6 100644 --- a/onboarding/onboarding.py +++ b/agrirouter/onboarding/onboarding.py @@ -1,12 +1,12 @@ import requests -from environments.environmental_services import EnvironmentalService -from onboarding.exceptions import RequestNotSigned -from onboarding.headers import SoftwareOnboardingHeader, CUOnboardingHeader -from onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, CUOnboardingParameter -from onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest -from onboarding.request_body import SoftwareOnboardingBody, CUOnboardingBody -from onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, CUOnboardingResponse +from agrirouter.environments.environmental_services import EnvironmentalService +from agrirouter.onboarding.exceptions import RequestNotSigned +from agrirouter.onboarding.headers import SoftwareOnboardingHeader, CUOnboardingHeader +from agrirouter.onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, CUOnboardingParameter +from agrirouter.onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest +from agrirouter.onboarding.request_body import SoftwareOnboardingBody, CUOnboardingBody +from agrirouter.onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, CUOnboardingResponse class SoftwareOnboarding(EnvironmentalService): diff --git a/onboarding/parameters.py b/agrirouter/onboarding/parameters.py similarity index 96% rename from onboarding/parameters.py rename to agrirouter/onboarding/parameters.py index 12f3373a..f88be38c 100644 --- a/onboarding/parameters.py +++ b/agrirouter/onboarding/parameters.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from constants.media_types import ContentTypes -from onboarding.enums import CertificateTypes +from agrirouter.constants.media_types import ContentTypes +from agrirouter.onboarding.enums import CertificateTypes class BaseOnboardingParameter(ABC): diff --git a/onboarding/request.py b/agrirouter/onboarding/request.py similarity index 80% rename from onboarding/request.py rename to agrirouter/onboarding/request.py index 8ec4258f..aae1e653 100644 --- a/onboarding/request.py +++ b/agrirouter/onboarding/request.py @@ -1,6 +1,6 @@ -from onboarding.headers import SoftwareOnboardingHeader, BaseOnboardingHeader -from onboarding.request_body import SoftwareOnboardingBody, BaseOnboardingBody -from onboarding.signature import create_signature +from agrirouter.onboarding.headers import SoftwareOnboardingHeader, BaseOnboardingHeader +from agrirouter.onboarding.request_body import SoftwareOnboardingBody, BaseOnboardingBody +from agrirouter.onboarding.signature import create_signature class BaseOnboardingRequest: diff --git a/onboarding/request_body.py b/agrirouter/onboarding/request_body.py similarity index 94% rename from onboarding/request_body.py rename to agrirouter/onboarding/request_body.py index 1d6c2ff2..d1c108eb 100644 --- a/onboarding/request_body.py +++ b/agrirouter/onboarding/request_body.py @@ -1,8 +1,8 @@ import json from abc import ABC, abstractmethod -from onboarding.enums import CertificateTypes, GateWays -from onboarding.exceptions import WrongCertificationType, WrongGateWay +from agrirouter.onboarding.enums import CertificateTypes, GateWays +from agrirouter.onboarding.exceptions import WrongCertificationType, WrongGateWay class BaseOnboardingBody(ABC): diff --git a/onboarding/response.py b/agrirouter/onboarding/response.py similarity index 100% rename from onboarding/response.py rename to agrirouter/onboarding/response.py diff --git a/onboarding/signature.py b/agrirouter/onboarding/signature.py similarity index 100% rename from onboarding/signature.py rename to agrirouter/onboarding/signature.py diff --git a/revoking/__init__.py b/agrirouter/revoking/__init__.py similarity index 100% rename from revoking/__init__.py rename to agrirouter/revoking/__init__.py diff --git a/revoking/headers.py b/agrirouter/revoking/headers.py similarity index 92% rename from revoking/headers.py rename to agrirouter/revoking/headers.py index 08dc878e..0c1770f2 100644 --- a/revoking/headers.py +++ b/agrirouter/revoking/headers.py @@ -1,4 +1,4 @@ -from constants.media_types import ContentTypes +from agrirouter.constants.media_types import ContentTypes class RevokingHeader: diff --git a/revoking/parameters.py b/agrirouter/revoking/parameters.py similarity index 94% rename from revoking/parameters.py rename to agrirouter/revoking/parameters.py index ef65d556..95a73332 100644 --- a/revoking/parameters.py +++ b/agrirouter/revoking/parameters.py @@ -1,4 +1,4 @@ -from constants.media_types import ContentTypes +from agrirouter.constants.media_types import ContentTypes class RevokingParameter: diff --git a/revoking/request.py b/agrirouter/revoking/request.py similarity index 84% rename from revoking/request.py rename to agrirouter/revoking/request.py index df80233e..d45b7787 100644 --- a/revoking/request.py +++ b/agrirouter/revoking/request.py @@ -1,6 +1,6 @@ -from onboarding.signature import create_signature -from revoking.headers import RevokingHeader -from revoking.request_body import RevokingBody +from agrirouter.onboarding.signature import create_signature +from agrirouter.revoking.headers import RevokingHeader +from agrirouter.revoking.request_body import RevokingBody class RevokingRequest: diff --git a/revoking/request_body.py b/agrirouter/revoking/request_body.py similarity index 100% rename from revoking/request_body.py rename to agrirouter/revoking/request_body.py diff --git a/revoking/response.py b/agrirouter/revoking/response.py similarity index 100% rename from revoking/response.py rename to agrirouter/revoking/response.py diff --git a/revoking/revoking.py b/agrirouter/revoking/revoking.py similarity index 75% rename from revoking/revoking.py rename to agrirouter/revoking/revoking.py index a1adb219..aaa8f871 100644 --- a/revoking/revoking.py +++ b/agrirouter/revoking/revoking.py @@ -1,12 +1,12 @@ import requests -from environments.environmental_services import EnvironmentalService -from onboarding.exceptions import RequestNotSigned -from revoking.headers import RevokingHeader -from revoking.parameters import RevokingParameter -from revoking.request import RevokingRequest -from revoking.request_body import RevokingBody -from revoking.response import RevokingResponse +from agrirouter.environments.environmental_services import EnvironmentalService +from agrirouter.onboarding.exceptions import RequestNotSigned +from agrirouter.revoking.headers import RevokingHeader +from agrirouter.revoking.parameters import RevokingParameter +from agrirouter.revoking.request import RevokingRequest +from agrirouter.revoking.request_body import RevokingBody +from agrirouter.revoking.response import RevokingResponse class Revoking(EnvironmentalService): From aa3ba7d761694bd463556f1caa48a2cea66c7b61 Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 5 Oct 2021 13:57:44 +0300 Subject: [PATCH 15/18] Add package config files (#3) --- .gitignore | 4 +++- agrirouter/__init__.py | 0 pyproject.toml | 3 +++ setup.py | 30 ++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 agrirouter/__init__.py create mode 100644 pyproject.toml create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 72ab21b1..25dda8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ +dist venv .idea **/__pycache__ +*.egg-info *.log *.log.* -.env \ No newline at end of file +.env diff --git a/agrirouter/__init__.py b/agrirouter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..9787c3bd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..8ca649fe --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup + +setup( + name='agrirouter-sdk-python', + version='1.0.0', + packages=['agrirouter'], + python_requires=">= 3.6", + url='https://github.com/DKE-Data/agrirouter-sdk-python', + license='Apache-2.0', + author='agrirouter', + author_email='info@dke-data.com', + description="""This project contains the API for the communication with the agrirouter. Everything you need for the + onboarding process, secure communication and much more.""", + classifiers=[ + 'Intended Audience :: Developers', + 'Natural Language :: English', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + ], + project_urls={ + 'Documentation': 'https://github.com/DKE-Data/agrirouter-sdk-python', + 'Source': 'https://github.com/DKE-Data/agrirouter-sdk-python', + }, +) From 8d35ed2b2e0526ba83f666a3776bb3764155295e Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 5 Oct 2021 21:02:04 +0300 Subject: [PATCH 16/18] Add initial documentation (#4) * Create LICENSE * Add dependencies to setup * Add assets * Add README * Add tests directory * Ignore build dir --- .gitignore | 1 + LICENSE | 201 +++++++++++++++++++++++++++++++++++ README.adoc | 67 ++++++++++++ assets/images/agrirouter.svg | 69 ++++++++++++ assets/images/lmis.svg | 79 ++++++++++++++ setup.py | 10 ++ tests/__init__.py | 0 7 files changed, 427 insertions(+) create mode 100644 LICENSE create mode 100644 README.adoc create mode 100755 assets/images/agrirouter.svg create mode 100644 assets/images/lmis.svg create mode 100644 tests/__init__.py diff --git a/.gitignore b/.gitignore index 25dda8a9..b8c6d657 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build dist venv .idea diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.adoc b/README.adoc new file mode 100644 index 00000000..59227151 --- /dev/null +++ b/README.adoc @@ -0,0 +1,67 @@ += agrirouter-sdk-python +:imagesdir: assets/images +:toc: +:toc-title: +:toclevels: 4 + +[abstract] +== Abstract +image::agrirouter.svg[agrirouter] + +The agrirouter is a universal data exchange platform for farmers and agricultural contractors that makes it possible to connect machinery and agricultural software, regardless of vendor or manufacturer. Agrirouter does not save data; it transfers data. +As a universal data exchange platform, agrirouter fills a gap on the way to Farming 4.0. Its underlying concept unites cross-vendor and discrimination-free data transfer. You retain full control over your data. Even data exchange with service providers (e.g. agricultural contractors) and other partners is uncomplicated: Data are very rapidly transferred via the online connection, and if you wish, is intelligently connected to other datasets. + +== Supporters & Maintainers +image::lmis.svg[agrirouter] + +The LMIS AG is a recognised german IT service company, certified according to DIN EN ISO 9001:2015 and based in +Osnabrück, Berlin, Friedland and Wuppertal. Our core competence is the individual development, optimisation and support +of IT solutions. We also provide professional IT consulting services and training courses. We have been supporting +the whole project during the development in the field of test management and are currently responsible for the development +support of the platform. + +We are active maintainers of the SDK and are using the SDK for internal testing purposes as well. Therefore, we have a +high interest in a stable and usable interface to connect to the agrirouter. + +Feel free to get in touch by visiting our https://www.lmis.de[website] or contacting us via GitHub. + +== The current project you're looking at + +This project contains the SDK for the communication with the agrirouter. Everything you need for the onboard process, secure communication and much more. + +== Installation + +The necessary dependencies are installed via `composer`. Just run the following command to add the SDK to your project. + + +`git clone https://github.com/DKE-Data/agrirouter-sdk-python.git` + +To install the SDK run the 'setup.py' script in the main directory (for a global install you will need to run this command with root privileges): + +`cd agrirouter-sdk-python` + +`virtualenv venv` + +`...` + +`$ . venv/bin/activate` + +`python setup.py install` + +For more install options type: + +`python setup.py --help` + +== Requirements + +Python 3.6 or above is required. + + +== External resources + +Here are some external resources for the development: + +* https://my-agrirouter.com[My Agrirouter Website] +* https://github.com/DKE-Data/agrirouter-interface-documentation[Integration Guide] +* https://www.aef-online.org[EFDI Protobuf Definition] +* https://www.lmis.de[LMIS - Maintenance & Support] diff --git a/assets/images/agrirouter.svg b/assets/images/agrirouter.svg new file mode 100755 index 00000000..c3d214b6 --- /dev/null +++ b/assets/images/agrirouter.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/lmis.svg b/assets/images/lmis.svg new file mode 100644 index 00000000..95e5da4a --- /dev/null +++ b/assets/images/lmis.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup.py b/setup.py index 8ca649fe..1d3753e5 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,16 @@ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', ], + install_requires=[ + 'certifi~=2021.5.30', + 'cffi~=1.14.6', + 'charset-normalizer~=2.0.6', + 'cryptography~=3.4.8', + 'idna~=3.2', + 'pycparser~=2.20', + 'requests~=2.26.0', + 'urllib3~=1.26.7' + ], project_urls={ 'Documentation': 'https://github.com/DKE-Data/agrirouter-sdk-python', 'Source': 'https://github.com/DKE-Data/agrirouter-sdk-python', diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b From 686eff30841f2f88f38ba5dd589f16237ca634f0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 6 Oct 2021 10:51:54 +0300 Subject: [PATCH 17/18] Clean up the README (#5) --- README.adoc | 24 +++---------- assets/images/lmis.svg | 79 ------------------------------------------ 2 files changed, 5 insertions(+), 98 deletions(-) delete mode 100644 assets/images/lmis.svg diff --git a/README.adoc b/README.adoc index 59227151..37137e1d 100644 --- a/README.adoc +++ b/README.adoc @@ -11,19 +11,6 @@ image::agrirouter.svg[agrirouter] The agrirouter is a universal data exchange platform for farmers and agricultural contractors that makes it possible to connect machinery and agricultural software, regardless of vendor or manufacturer. Agrirouter does not save data; it transfers data. As a universal data exchange platform, agrirouter fills a gap on the way to Farming 4.0. Its underlying concept unites cross-vendor and discrimination-free data transfer. You retain full control over your data. Even data exchange with service providers (e.g. agricultural contractors) and other partners is uncomplicated: Data are very rapidly transferred via the online connection, and if you wish, is intelligently connected to other datasets. -== Supporters & Maintainers -image::lmis.svg[agrirouter] - -The LMIS AG is a recognised german IT service company, certified according to DIN EN ISO 9001:2015 and based in -Osnabrück, Berlin, Friedland and Wuppertal. Our core competence is the individual development, optimisation and support -of IT solutions. We also provide professional IT consulting services and training courses. We have been supporting -the whole project during the development in the field of test management and are currently responsible for the development -support of the platform. - -We are active maintainers of the SDK and are using the SDK for internal testing purposes as well. Therefore, we have a -high interest in a stable and usable interface to connect to the agrirouter. - -Feel free to get in touch by visiting our https://www.lmis.de[website] or contacting us via GitHub. == The current project you're looking at @@ -34,23 +21,23 @@ This project contains the SDK for the communication with the agrirouter. Everyth The necessary dependencies are installed via `composer`. Just run the following command to add the SDK to your project. -`git clone https://github.com/DKE-Data/agrirouter-sdk-python.git` +`$ git clone https://github.com/DKE-Data/agrirouter-sdk-python.git` To install the SDK run the 'setup.py' script in the main directory (for a global install you will need to run this command with root privileges): -`cd agrirouter-sdk-python` +`$ cd agrirouter-sdk-python` -`virtualenv venv` +`$ virtualenv venv` `...` `$ . venv/bin/activate` -`python setup.py install` +`$ python setup.py install` For more install options type: -`python setup.py --help` +`$ python setup.py --help` == Requirements @@ -64,4 +51,3 @@ Here are some external resources for the development: * https://my-agrirouter.com[My Agrirouter Website] * https://github.com/DKE-Data/agrirouter-interface-documentation[Integration Guide] * https://www.aef-online.org[EFDI Protobuf Definition] -* https://www.lmis.de[LMIS - Maintenance & Support] diff --git a/assets/images/lmis.svg b/assets/images/lmis.svg deleted file mode 100644 index 95e5da4a..00000000 --- a/assets/images/lmis.svg +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 45e7654118168c42846b3352044a76b3ff12ce96 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 13 Oct 2021 14:57:37 +0300 Subject: [PATCH 18/18] Implement messaging (#8) * Implement get_connection_criteria, get_sensor_alternate_id, get_authentication methods for BaseOnboardingResonse * Implement messaging/dto parameters * Create protobuf classes for messages * Implement certification for messaging * Create AbstractClient, HttpMessagingClient, MqttMessagingClient * Add prtobuf library to requirements * Create MessageHeaderParameters, MessagePayloadParameters * Add paho-mqtt to requirements * Fix MqttMessagingClient * Create cloud_virtualized_app_registration_pb2.py protobuf file * Create utils * Fix imports in protobuf generated files * Implement encoding messages * Implement decoding messages * Implement mqtt client * Implement MQttMessagingService. Refactor HttpMessagingService * Refactor messaging/parameters * Decoded Message * Create TypeUrlNotFoundError * Create TypeUrl service * Refactor messaging/decode * Fix generated/cload_virtualized_add_registration * Create TechnicalMessageType enum * Rename function encode to encode_messge * Implement MessagingServiceParameters * Implement MEssagingServices classes * Add AR Public Keys to handle signature verification * Refactor auth * Implement QueryMessagesService, QueryHeaderService * Implement OutboxService * Implement CloudOnboardService, CloudOffboardService * Fix SoftwareOnboardingHeader.sign() method * Fix imports * Create examples file * Add unit tests (#6) * Move main classes to agrirouter/__init__.py * Update examples.txt * Fix examples.txt * Fix examples.txt * Fix SoftwareOnboardingHeader * Fix onboarding * Implement messaging certification * Fix onboarding headers signing * Refactor onboarding request body * Refactor onboarding parameters * Refactor onboarding client * Fix requests certification in messaging * Refactor messaging certification --- .gitignore | 1 + README.adoc | 3 + agrirouter/__init__.py | 17 + agrirouter/auth/auth.py | 4 +- agrirouter/auth/response.py | 20 +- agrirouter/clients/clients.py | 29 - agrirouter/environments/environments.py | 11 + agrirouter/environments/keys.py | 19 + .../cloud_virtualized_app_registration_pb2.py | 325 ++++++++ agrirouter/generated/commons/chunk_pb2.py | 91 +++ agrirouter/generated/commons/message_pb2.py | 214 ++++++ .../request/payload/account/endpoints_pb2.py | 110 +++ .../payload/endpoint/capabilities_pb2.py | 205 +++++ .../payload/endpoint/subscription_pb2.py | 125 +++ .../request/payload/feed/feed_requests_pb2.py | 231 ++++++ .../messaging/request/request_pb2.py | 208 +++++ .../response/payload/account/endpoints_pb2.py | 227 ++++++ .../payload/endpoint/capability_pb2.py | 125 +++ .../payload/feed/feed_response_pb2.py | 710 ++++++++++++++++++ .../payload/feed/push_notification_pb2.py | 239 ++++++ .../messaging/response/response_pb2.py | 211 ++++++ .../generated/settings/dh_settings_pb2.py | 77 ++ agrirouter/{clients => messaging}/__init__.py | 0 agrirouter/messaging/certification.py | 23 + .../messaging/clients}/__init__.py | 0 agrirouter/messaging/clients/http.py | 22 + agrirouter/messaging/clients/mqtt.py | 138 ++++ agrirouter/messaging/decode.py | 50 ++ agrirouter/messaging/encode.py | 46 ++ agrirouter/messaging/enums.py | 15 + agrirouter/messaging/exceptions.py | 9 + agrirouter/messaging/messages.py | 115 +++ .../parameters/__init__.py} | 0 agrirouter/messaging/parameters/dto.py | 91 +++ agrirouter/messaging/parameters/service.py | 348 +++++++++ agrirouter/messaging/request.py | 25 + agrirouter/messaging/result.py | 47 ++ .../services/__init__.py} | 0 agrirouter/messaging/services/cloud.py | 71 ++ agrirouter/messaging/services/commons.py | 90 +++ .../messaging/services/http/__init__.py | 0 agrirouter/messaging/services/http/outbox.py | 30 + agrirouter/messaging/services/messaging.py | 254 +++++++ agrirouter/onboarding/headers.py | 10 +- agrirouter/onboarding/onboarding.py | 7 +- agrirouter/onboarding/parameters.py | 9 +- agrirouter/onboarding/request.py | 2 +- agrirouter/onboarding/request_body.py | 15 +- agrirouter/onboarding/response.py | 25 +- agrirouter/utils/__init__.py | 0 agrirouter/utils/type_url.py | 45 ++ agrirouter/utils/utc_time_util.py | 6 + agrirouter/utils/uuid_util.py | 5 + conftest.py | 13 + examples.txt | 72 ++ requirements.txt | 6 + tests/auth_test/test_response.py | 22 + tests/constants.py | 60 ++ .../test_environmental_services.py | 11 + tests/enviroments_test/test_environments.py | 213 ++++++ tests/messaging_test/test_request.py | 15 + tests/onboarding_test/test_headers.py | 23 + tox.ini | 16 + 63 files changed, 5095 insertions(+), 56 deletions(-) delete mode 100644 agrirouter/clients/clients.py create mode 100644 agrirouter/environments/keys.py create mode 100644 agrirouter/generated/cloud_provider_integration/cloud_virtualized_app_registration_pb2.py create mode 100644 agrirouter/generated/commons/chunk_pb2.py create mode 100644 agrirouter/generated/commons/message_pb2.py create mode 100644 agrirouter/generated/messaging/request/payload/account/endpoints_pb2.py create mode 100644 agrirouter/generated/messaging/request/payload/endpoint/capabilities_pb2.py create mode 100644 agrirouter/generated/messaging/request/payload/endpoint/subscription_pb2.py create mode 100644 agrirouter/generated/messaging/request/payload/feed/feed_requests_pb2.py create mode 100644 agrirouter/generated/messaging/request/request_pb2.py create mode 100644 agrirouter/generated/messaging/response/payload/account/endpoints_pb2.py create mode 100644 agrirouter/generated/messaging/response/payload/endpoint/capability_pb2.py create mode 100644 agrirouter/generated/messaging/response/payload/feed/feed_response_pb2.py create mode 100644 agrirouter/generated/messaging/response/payload/feed/push_notification_pb2.py create mode 100644 agrirouter/generated/messaging/response/response_pb2.py create mode 100644 agrirouter/generated/settings/dh_settings_pb2.py rename agrirouter/{clients => messaging}/__init__.py (100%) create mode 100644 agrirouter/messaging/certification.py rename {tests => agrirouter/messaging/clients}/__init__.py (100%) create mode 100644 agrirouter/messaging/clients/http.py create mode 100644 agrirouter/messaging/clients/mqtt.py create mode 100644 agrirouter/messaging/decode.py create mode 100644 agrirouter/messaging/encode.py create mode 100644 agrirouter/messaging/enums.py create mode 100644 agrirouter/messaging/exceptions.py create mode 100644 agrirouter/messaging/messages.py rename agrirouter/{constants/keys.py => messaging/parameters/__init__.py} (100%) create mode 100644 agrirouter/messaging/parameters/dto.py create mode 100644 agrirouter/messaging/parameters/service.py create mode 100644 agrirouter/messaging/request.py create mode 100644 agrirouter/messaging/result.py rename agrirouter/{environments/enums.py => messaging/services/__init__.py} (100%) create mode 100644 agrirouter/messaging/services/cloud.py create mode 100644 agrirouter/messaging/services/commons.py create mode 100644 agrirouter/messaging/services/http/__init__.py create mode 100644 agrirouter/messaging/services/http/outbox.py create mode 100644 agrirouter/messaging/services/messaging.py create mode 100644 agrirouter/utils/__init__.py create mode 100644 agrirouter/utils/type_url.py create mode 100644 agrirouter/utils/utc_time_util.py create mode 100644 agrirouter/utils/uuid_util.py create mode 100644 conftest.py create mode 100644 examples.txt create mode 100644 tests/auth_test/test_response.py create mode 100644 tests/constants.py create mode 100644 tests/enviroments_test/test_environmental_services.py create mode 100644 tests/enviroments_test/test_environments.py create mode 100644 tests/messaging_test/test_request.py create mode 100644 tests/onboarding_test/test_headers.py create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index b8c6d657..980ae2ce 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ venv *.log *.log.* .env +.pytest_cache \ No newline at end of file diff --git a/README.adoc b/README.adoc index 37137e1d..a8a74271 100644 --- a/README.adoc +++ b/README.adoc @@ -43,6 +43,9 @@ For more install options type: Python 3.6 or above is required. +== Running unit tests + +`$ pytest` == External resources diff --git a/agrirouter/__init__.py b/agrirouter/__init__.py index e69de29b..ad6ecf05 100644 --- a/agrirouter/__init__.py +++ b/agrirouter/__init__.py @@ -0,0 +1,17 @@ +from agrirouter.auth.auth import Authorization +from agrirouter.auth.parameters import AuthUrlParameter + +from agrirouter.onboarding.onboarding import SoftwareOnboarding +from agrirouter.onboarding.parameters import SoftwareOnboardingParameter + +from agrirouter.revoking.revoking import Revoking +from agrirouter.revoking.parameters import RevokingParameter + +from agrirouter.messaging.parameters.service import MessageHeaderParameters, MessagePayloadParameters, \ + QueryMessageParameters, QueryHeaderParameters, CloudOffboardParameters, CloudOnboardParameters, \ + CapabilityParameters, FeedConfirmParameters, FeedDeleteParameters, ListEndpointsParameters, MessageParameters, \ + SubscriptionParameters +from agrirouter.messaging.services.cloud import CloudOnboardService, CloudOffboardService +from agrirouter.messaging.services.messaging import SubscriptionService, CapabilityService, FeedConfirmService,\ + FeedDeleteService, QueryHeaderService, QueryMessagesService, ListEndpointsService + diff --git a/agrirouter/auth/auth.py b/agrirouter/auth/auth.py index fa9e2e9a..6cf1902b 100644 --- a/agrirouter/auth/auth.py +++ b/agrirouter/auth/auth.py @@ -26,8 +26,8 @@ def extract_auth_response(self, url: str) -> AuthResponse: query_params = self._extract_query_params(parsed_url.query) return AuthResponse(query_params) - @staticmethod - def verify_auth_response(response, public_key): + def verify_auth_response(self, response, public_key=None): + public_key = public_key if public_key else self._environment.get_env_public_key() response.verify(public_key) @staticmethod diff --git a/agrirouter/auth/response.py b/agrirouter/auth/response.py index 3e4f1067..a711c4a6 100644 --- a/agrirouter/auth/response.py +++ b/agrirouter/auth/response.py @@ -22,7 +22,16 @@ def __init__(self, query_params): self._token = query_params.get(self.TOKEN_KEY, None) self._error = query_params.get(self.ERROR_KEY, None) self.is_successful = not bool(self._error) - self.is_valid = False + self._was_verified = False + self._is_valid = False + + @property + def is_valid(self): + if not self._was_verified: + raise PermissionError("The response was not verified yet. Please verify first. " + "You can access is_valid only after verifying") + + return self._is_valid def verify(self, public_key) -> None: """ @@ -37,13 +46,14 @@ def verify(self, public_key) -> None: encoded_data = self._state + self._token unquoted_signature = unquote(self._signature) encoded_signature = base64.b64decode(unquoted_signature.encode("utf-8")) + self._was_verified = True try: verify_signature(encoded_data, encoded_signature, public_key) except InvalidSignature: print("Response is invalid: invalid signature.") - self.is_valid = False + self._is_valid = False - self.is_valid = True + self._is_valid = True @staticmethod def decode_token(token: Union[str, bytes]) -> dict: @@ -63,7 +73,3 @@ def get_auth_result(self) -> dict: self.TOKEN_KEY: self._token, self.CRED_KEY: decoded_token } - - -def decorator(func): - pass diff --git a/agrirouter/clients/clients.py b/agrirouter/clients/clients.py deleted file mode 100644 index f42483ae..00000000 --- a/agrirouter/clients/clients.py +++ /dev/null @@ -1,29 +0,0 @@ -from agrirouter.environments.environments import ProductionEnvironment, QAEnvironment - - -class InvalidEnvironmentSetup(Exception): - def __init__(self, message=None, env=None): - if not message: - message = "Invalid value of env parameter. [QA] or [Production] values are allowed" - self.message = message - self.env = env - - -class ARClient: - - def __init__(self, env): - self._set_env(env) - - def authenticate(self): - auth_link = self._create_auth_link() - - def _create_auth_link(self): - return "" - - def _set_env(self, env): - if env == "QA": - self._environment = QAEnvironment - if env == "Production": - return ProductionEnvironment - else: - raise InvalidEnvironmentSetup(env=env) diff --git a/agrirouter/environments/environments.py b/agrirouter/environments/environments.py index 9e6d75b2..503ecd6b 100644 --- a/agrirouter/environments/environments.py +++ b/agrirouter/environments/environments.py @@ -1,3 +1,5 @@ +from agrirouter.environments.keys import AR_QA_PUBLIC_KEY, AR_PROD_PUBLIC_KEY + class BaseEnvironment: _AGRIROUTER_LOGIN_URL = "/app" @@ -10,6 +12,8 @@ class BaseEnvironment: _API_PREFIX = "" _REGISTRATION_SERVICE_URL = "" + AR_PUBLIC_KEY = None + def get_base_url(self) -> str: return self._ENV_BASE_URL @@ -45,14 +49,21 @@ def get_secured_onboarding_authorization_url(self, application_id, response_type def get_mqtt_server_url(self, host, port) -> str: return self._MQTT_URL_TEMPLATE.format(host=host, port=port) + def get_env_public_key(self): + return self.AR_PUBLIC_KEY + class ProductionEnvironment(BaseEnvironment): _ENV_BASE_URL = "https://goto.my-agrirouter.com" _API_PREFIX = "/api/v1.0" _REGISTRATION_SERVICE_URL = "https://onboard.my-agrirouter.com" + AR_PUBLIC_KEY = AR_PROD_PUBLIC_KEY + class QAEnvironment(BaseEnvironment): _ENV_BASE_URL = "https://agrirouter-qa.cfapps.eu10.hana.ondemand.com" _API_PREFIX = "/api/v1.0" _REGISTRATION_SERVICE_URL = "https://agrirouter-registration-service-hubqa-eu10.cfapps.eu10.hana.ondemand.com" + + AR_PUBLIC_KEY = AR_QA_PUBLIC_KEY diff --git a/agrirouter/environments/keys.py b/agrirouter/environments/keys.py new file mode 100644 index 00000000..7ed3a292 --- /dev/null +++ b/agrirouter/environments/keys.py @@ -0,0 +1,19 @@ +AR_QA_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" \ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8xF9661acn+iS+QS+9Y\n" \ + "3HvTfUVcismzbuvxHgHA7YeoOUFxyj3lkaTnXm7hzQe4wDEDgwpJSGAzxIIYSUXe\n" \ + "8EsWLorg5O0tRexx5SP3+kj1i83DATBJCXP7k+bAF4u2FVJphC1m2BfLxelGLjzx\n" \ + "VAS/v6+EwvYaT1AI9FFqW/a2o92IsVPOh9oM9eds3lBOAbH/8XrmVIeHofw+XbTH\n" \ + "1/7MLD6IE2+HbEeY0F96nioXArdQWXcjUQsTch+p0p9eqh23Ak4ef5oGcZhNd4yp\n" \ + "Y8M6ppvIMiXkgWSPJevCJjhxRJRmndY+ajYGx7CLePx7wNvxXWtkng3yh+7WiZ/Y\n" \ + "qwIDAQAB\n" \ + "-----END PUBLIC KEY-----" + +AR_PROD_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" \ + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCxD31sYtzH9NTfZ6n8H\n" \ + "+H/QgOaoTL9GAakplAsdwYSLjBpgYMZOHIgkdM9ksRP8WsITChtZtxrCnBjR8bap\n" \ + "ekPT/pM9zPZlNEPxUlylJNwwTWjzTJP03+Yr07Q8v8fTJ5VWzAHlHtGQ/sI7yXA8\n" \ + "pzruTNre1MzxO3lkljt2Q2e7CVXAp1b53BghgysppL9Bl7NK1R+vdWSs0B1Db/Gj\n" \ + "alOkWUnhivTjRMX61RGDCQSVSEaX12EvJX7FooAsW3NFeZCgeZGWEa5ZMALIiBL4\n" \ + "GNASOOHju7ewlYjkyGIRxxAoc3C0w5dg1qlLiAFWToYwgDOcUpLRjU/7bzGiGvp8\n" \ + "RwIDAQAB\n" \ + "-----END PUBLIC KEY-----" diff --git a/agrirouter/generated/cloud_provider_integration/cloud_virtualized_app_registration_pb2.py b/agrirouter/generated/cloud_provider_integration/cloud_virtualized_app_registration_pb2.py new file mode 100644 index 00000000..2ce2e547 --- /dev/null +++ b/agrirouter/generated/cloud_provider_integration/cloud_virtualized_app_registration_pb2.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: cloud-provider-integration/cloud-virtualized-app-registration.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from agrirouter.generated.commons import message_pb2 as commons_dot_message__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='cloud-provider-integration/cloud-virtualized-app-registration.proto', + package='agrirouter.cloud.registration', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\nCcloud-provider-integration/cloud-virtualized-app-registration.proto\x12\x1d\x61grirouter.cloud.registration\x1a\x15\x63ommons/message.proto\"\xb7\x01\n\x11OnboardingRequest\x12i\n\x13onboarding_requests\x18\x01 \x03(\x0b\x32L.agrirouter.cloud.registration.OnboardingRequest.EndpointRegistrationDetails\x1a\x37\n\x1b\x45ndpointRegistrationDetails\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xaf\x03\n\x12OnboardingResponse\x12j\n\x13onboarded_endpoints\x18\x01 \x03(\x0b\x32M.agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails\x12L\n\x08\x66\x61ilures\x18\x02 \x03(\x0b\x32:.agrirouter.cloud.registration.OnboardingResponse.Failures\x1a\x99\x01\n\x1b\x45ndpointRegistrationDetails\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1b\n\x13\x64\x65vice_alternate_id\x18\x02 \x01(\t\x12\x1b\n\x13sensor_alternate_id\x18\x03 \x01(\t\x12\x1f\n\x17\x63\x61pability_alternate_id\x18\x04 \x01(\t\x12\x13\n\x0b\x65ndpoint_id\x18\x05 \x01(\t\x1a\x43\n\x08\x46\x61ilures\x12\n\n\x02id\x18\x01 \x01(\t\x12+\n\x06reason\x18\x02 \x01(\x0b\x32\x1b.agrirouter.commons.Message\"\'\n\x12OffboardingRequest\x12\x11\n\tendpoints\x18\x01 \x03(\tb\x06proto3' + , + dependencies=[commons_dot_message__pb2.DESCRIPTOR,]) + + + + +_ONBOARDINGREQUEST_ENDPOINTREGISTRATIONDETAILS = _descriptor.Descriptor( + name='EndpointRegistrationDetails', + full_name='agrirouter.cloud.registration.OnboardingRequest.EndpointRegistrationDetails', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='agrirouter.cloud.registration.OnboardingRequest.EndpointRegistrationDetails.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='name', full_name='agrirouter.cloud.registration.OnboardingRequest.EndpointRegistrationDetails.name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=254, + serialized_end=309, +) + +_ONBOARDINGREQUEST = _descriptor.Descriptor( + name='OnboardingRequest', + full_name='agrirouter.cloud.registration.OnboardingRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='onboarding_requests', full_name='agrirouter.cloud.registration.OnboardingRequest.onboarding_requests', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_ONBOARDINGREQUEST_ENDPOINTREGISTRATIONDETAILS, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=126, + serialized_end=309, +) + + +_ONBOARDINGRESPONSE_ENDPOINTREGISTRATIONDETAILS = _descriptor.Descriptor( + name='EndpointRegistrationDetails', + full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='device_alternate_id', full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails.device_alternate_id', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sensor_alternate_id', full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails.sensor_alternate_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='capability_alternate_id', full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails.capability_alternate_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='endpoint_id', full_name='agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails.endpoint_id', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=521, + serialized_end=674, +) + +_ONBOARDINGRESPONSE_FAILURES = _descriptor.Descriptor( + name='Failures', + full_name='agrirouter.cloud.registration.OnboardingResponse.Failures', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='agrirouter.cloud.registration.OnboardingResponse.Failures.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reason', full_name='agrirouter.cloud.registration.OnboardingResponse.Failures.reason', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=676, + serialized_end=743, +) + +_ONBOARDINGRESPONSE = _descriptor.Descriptor( + name='OnboardingResponse', + full_name='agrirouter.cloud.registration.OnboardingResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='onboarded_endpoints', full_name='agrirouter.cloud.registration.OnboardingResponse.onboarded_endpoints', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='failures', full_name='agrirouter.cloud.registration.OnboardingResponse.failures', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_ONBOARDINGRESPONSE_ENDPOINTREGISTRATIONDETAILS, _ONBOARDINGRESPONSE_FAILURES, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=312, + serialized_end=743, +) + + +_OFFBOARDINGREQUEST = _descriptor.Descriptor( + name='OffboardingRequest', + full_name='agrirouter.cloud.registration.OffboardingRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='endpoints', full_name='agrirouter.cloud.registration.OffboardingRequest.endpoints', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=745, + serialized_end=784, +) + +_ONBOARDINGREQUEST_ENDPOINTREGISTRATIONDETAILS.containing_type = _ONBOARDINGREQUEST +_ONBOARDINGREQUEST.fields_by_name['onboarding_requests'].message_type = _ONBOARDINGREQUEST_ENDPOINTREGISTRATIONDETAILS +_ONBOARDINGRESPONSE_ENDPOINTREGISTRATIONDETAILS.containing_type = _ONBOARDINGRESPONSE +_ONBOARDINGRESPONSE_FAILURES.fields_by_name['reason'].message_type = commons_dot_message__pb2._MESSAGE +_ONBOARDINGRESPONSE_FAILURES.containing_type = _ONBOARDINGRESPONSE +_ONBOARDINGRESPONSE.fields_by_name['onboarded_endpoints'].message_type = _ONBOARDINGRESPONSE_ENDPOINTREGISTRATIONDETAILS +_ONBOARDINGRESPONSE.fields_by_name['failures'].message_type = _ONBOARDINGRESPONSE_FAILURES +DESCRIPTOR.message_types_by_name['OnboardingRequest'] = _ONBOARDINGREQUEST +DESCRIPTOR.message_types_by_name['OnboardingResponse'] = _ONBOARDINGRESPONSE +DESCRIPTOR.message_types_by_name['OffboardingRequest'] = _OFFBOARDINGREQUEST +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +OnboardingRequest = _reflection.GeneratedProtocolMessageType('OnboardingRequest', (_message.Message,), { + + 'EndpointRegistrationDetails' : _reflection.GeneratedProtocolMessageType('EndpointRegistrationDetails', (_message.Message,), { + 'DESCRIPTOR' : _ONBOARDINGREQUEST_ENDPOINTREGISTRATIONDETAILS, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OnboardingRequest.EndpointRegistrationDetails) + }) + , + 'DESCRIPTOR' : _ONBOARDINGREQUEST, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OnboardingRequest) + }) +_sym_db.RegisterMessage(OnboardingRequest) +_sym_db.RegisterMessage(OnboardingRequest.EndpointRegistrationDetails) + +OnboardingResponse = _reflection.GeneratedProtocolMessageType('OnboardingResponse', (_message.Message,), { + + 'EndpointRegistrationDetails' : _reflection.GeneratedProtocolMessageType('EndpointRegistrationDetails', (_message.Message,), { + 'DESCRIPTOR' : _ONBOARDINGRESPONSE_ENDPOINTREGISTRATIONDETAILS, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OnboardingResponse.EndpointRegistrationDetails) + }) + , + + 'Failures' : _reflection.GeneratedProtocolMessageType('Failures', (_message.Message,), { + 'DESCRIPTOR' : _ONBOARDINGRESPONSE_FAILURES, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OnboardingResponse.Failures) + }) + , + 'DESCRIPTOR' : _ONBOARDINGRESPONSE, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OnboardingResponse) + }) +_sym_db.RegisterMessage(OnboardingResponse) +_sym_db.RegisterMessage(OnboardingResponse.EndpointRegistrationDetails) +_sym_db.RegisterMessage(OnboardingResponse.Failures) + +OffboardingRequest = _reflection.GeneratedProtocolMessageType('OffboardingRequest', (_message.Message,), { + 'DESCRIPTOR' : _OFFBOARDINGREQUEST, + '__module__' : 'cloud_provider_integration.cloud_virtualized_app_registration_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.cloud.registration.OffboardingRequest) + }) +_sym_db.RegisterMessage(OffboardingRequest) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/commons/chunk_pb2.py b/agrirouter/generated/commons/chunk_pb2.py new file mode 100644 index 00000000..005fddf2 --- /dev/null +++ b/agrirouter/generated/commons/chunk_pb2.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: commons/chunk.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='commons/chunk.proto', + package='agrirouter.commons', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x13\x63ommons/chunk.proto\x12\x12\x61grirouter.commons\"X\n\x0e\x43hunkComponent\x12\x12\n\ncontext_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\x03\x12\r\n\x05total\x18\x03 \x01(\x03\x12\x12\n\ntotal_size\x18\x04 \x01(\x03\x62\x06proto3' +) + + + + +_CHUNKCOMPONENT = _descriptor.Descriptor( + name='ChunkComponent', + full_name='agrirouter.commons.ChunkComponent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='context_id', full_name='agrirouter.commons.ChunkComponent.context_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='current', full_name='agrirouter.commons.ChunkComponent.current', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='total', full_name='agrirouter.commons.ChunkComponent.total', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='total_size', full_name='agrirouter.commons.ChunkComponent.total_size', index=3, + number=4, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=43, + serialized_end=131, +) + +DESCRIPTOR.message_types_by_name['ChunkComponent'] = _CHUNKCOMPONENT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ChunkComponent = _reflection.GeneratedProtocolMessageType('ChunkComponent', (_message.Message,), { + 'DESCRIPTOR' : _CHUNKCOMPONENT, + '__module__' : 'commons.chunk_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.commons.ChunkComponent) + }) +_sym_db.RegisterMessage(ChunkComponent) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/commons/message_pb2.py b/agrirouter/generated/commons/message_pb2.py new file mode 100644 index 00000000..73433729 --- /dev/null +++ b/agrirouter/generated/commons/message_pb2.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: commons/message.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='commons/message.proto', + package='agrirouter.commons', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x15\x63ommons/message.proto\x12\x12\x61grirouter.commons\"\x92\x01\n\x07Message\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x14\n\x0cmessage_code\x18\x02 \x01(\t\x12\x33\n\x04\x61rgs\x18\x03 \x03(\x0b\x32%.agrirouter.commons.Message.ArgsEntry\x1a+\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x1d\n\x08Metadata\x12\x11\n\tfile_name\x18\x01 \x01(\t\"9\n\x08Messages\x12-\n\x08messages\x18\x01 \x03(\x0b\x32\x1b.agrirouter.commons.Messageb\x06proto3' +) + + + + +_MESSAGE_ARGSENTRY = _descriptor.Descriptor( + name='ArgsEntry', + full_name='agrirouter.commons.Message.ArgsEntry', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='agrirouter.commons.Message.ArgsEntry.key', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='value', full_name='agrirouter.commons.Message.ArgsEntry.value', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=b'8\001', + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=149, + serialized_end=192, +) + +_MESSAGE = _descriptor.Descriptor( + name='Message', + full_name='agrirouter.commons.Message', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='agrirouter.commons.Message.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_code', full_name='agrirouter.commons.Message.message_code', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='args', full_name='agrirouter.commons.Message.args', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_MESSAGE_ARGSENTRY, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=46, + serialized_end=192, +) + + +_METADATA = _descriptor.Descriptor( + name='Metadata', + full_name='agrirouter.commons.Metadata', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='file_name', full_name='agrirouter.commons.Metadata.file_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=194, + serialized_end=223, +) + + +_MESSAGES = _descriptor.Descriptor( + name='Messages', + full_name='agrirouter.commons.Messages', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='messages', full_name='agrirouter.commons.Messages.messages', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=225, + serialized_end=282, +) + +_MESSAGE_ARGSENTRY.containing_type = _MESSAGE +_MESSAGE.fields_by_name['args'].message_type = _MESSAGE_ARGSENTRY +_MESSAGES.fields_by_name['messages'].message_type = _MESSAGE +DESCRIPTOR.message_types_by_name['Message'] = _MESSAGE +DESCRIPTOR.message_types_by_name['Metadata'] = _METADATA +DESCRIPTOR.message_types_by_name['Messages'] = _MESSAGES +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), { + + 'ArgsEntry' : _reflection.GeneratedProtocolMessageType('ArgsEntry', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGE_ARGSENTRY, + '__module__' : 'commons.message_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.commons.Message.ArgsEntry) + }) + , + 'DESCRIPTOR' : _MESSAGE, + '__module__' : 'commons.message_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.commons.Message) + }) +_sym_db.RegisterMessage(Message) +_sym_db.RegisterMessage(Message.ArgsEntry) + +Metadata = _reflection.GeneratedProtocolMessageType('Metadata', (_message.Message,), { + 'DESCRIPTOR' : _METADATA, + '__module__' : 'commons.message_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.commons.Metadata) + }) +_sym_db.RegisterMessage(Metadata) + +Messages = _reflection.GeneratedProtocolMessageType('Messages', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGES, + '__module__' : 'commons.message_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.commons.Messages) + }) +_sym_db.RegisterMessage(Messages) + + +_MESSAGE_ARGSENTRY._options = None +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/request/payload/account/endpoints_pb2.py b/agrirouter/generated/messaging/request/payload/account/endpoints_pb2.py new file mode 100644 index 00000000..15313f5d --- /dev/null +++ b/agrirouter/generated/messaging/request/payload/account/endpoints_pb2.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/request/payload/account/endpoints.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/request/payload/account/endpoints.proto', + package='agrirouter.request.payload.account', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n1messaging/request/payload/account/endpoints.proto\x12\"agrirouter.request.payload.account\"\xbf\x01\n\x12ListEndpointsQuery\x12\x1e\n\x16technical_message_type\x18\x01 \x01(\t\x12S\n\tdirection\x18\x02 \x01(\x0e\x32@.agrirouter.request.payload.account.ListEndpointsQuery.Direction\"4\n\tDirection\x12\x08\n\x04SEND\x10\x00\x12\x0b\n\x07RECEIVE\x10\x01\x12\x10\n\x0cSEND_RECEIVE\x10\x02\x62\x06proto3' +) + + + +_LISTENDPOINTSQUERY_DIRECTION = _descriptor.EnumDescriptor( + name='Direction', + full_name='agrirouter.request.payload.account.ListEndpointsQuery.Direction', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='SEND', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RECEIVE', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SEND_RECEIVE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=229, + serialized_end=281, +) +_sym_db.RegisterEnumDescriptor(_LISTENDPOINTSQUERY_DIRECTION) + + +_LISTENDPOINTSQUERY = _descriptor.Descriptor( + name='ListEndpointsQuery', + full_name='agrirouter.request.payload.account.ListEndpointsQuery', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.request.payload.account.ListEndpointsQuery.technical_message_type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='direction', full_name='agrirouter.request.payload.account.ListEndpointsQuery.direction', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _LISTENDPOINTSQUERY_DIRECTION, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=90, + serialized_end=281, +) + +_LISTENDPOINTSQUERY.fields_by_name['direction'].enum_type = _LISTENDPOINTSQUERY_DIRECTION +_LISTENDPOINTSQUERY_DIRECTION.containing_type = _LISTENDPOINTSQUERY +DESCRIPTOR.message_types_by_name['ListEndpointsQuery'] = _LISTENDPOINTSQUERY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ListEndpointsQuery = _reflection.GeneratedProtocolMessageType('ListEndpointsQuery', (_message.Message,), { + 'DESCRIPTOR' : _LISTENDPOINTSQUERY, + '__module__' : 'messaging.request.payload.account.endpoints_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.payload.account.ListEndpointsQuery) + }) +_sym_db.RegisterMessage(ListEndpointsQuery) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/request/payload/endpoint/capabilities_pb2.py b/agrirouter/generated/messaging/request/payload/endpoint/capabilities_pb2.py new file mode 100644 index 00000000..a31856ca --- /dev/null +++ b/agrirouter/generated/messaging/request/payload/endpoint/capabilities_pb2.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/request/payload/endpoint/capabilities.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/request/payload/endpoint/capabilities.proto', + package='agrirouter.request.payload.endpoint', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n5messaging/request/payload/endpoint/capabilities.proto\x12#agrirouter.request.payload.endpoint\"\xb9\x04\n\x17\x43\x61pabilitySpecification\x12]\n\x0c\x63\x61pabilities\x18\x01 \x03(\x0b\x32G.agrirouter.request.payload.endpoint.CapabilitySpecification.Capability\x12\x1c\n\x14\x61pp_certification_id\x18\x02 \x01(\t\x12$\n\x1c\x61pp_certification_version_id\x18\x03 \x01(\t\x12p\n\x19\x65nable_push_notifications\x18\x04 \x01(\x0e\x32M.agrirouter.request.payload.endpoint.CapabilitySpecification.PushNotification\x1a\x87\x01\n\nCapability\x12\x1e\n\x16technical_message_type\x18\x01 \x01(\t\x12Y\n\tdirection\x18\x02 \x01(\x0e\x32\x46.agrirouter.request.payload.endpoint.CapabilitySpecification.Direction\"4\n\tDirection\x12\x08\n\x04SEND\x10\x00\x12\x0b\n\x07RECEIVE\x10\x01\x12\x10\n\x0cSEND_RECEIVE\x10\x02\"I\n\x10PushNotification\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x1a\n\x16\x45NABLED_HIGH_FREQUENCY\x10\x02\x62\x06proto3' +) + + + +_CAPABILITYSPECIFICATION_DIRECTION = _descriptor.EnumDescriptor( + name='Direction', + full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.Direction', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='SEND', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RECEIVE', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SEND_RECEIVE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=537, + serialized_end=589, +) +_sym_db.RegisterEnumDescriptor(_CAPABILITYSPECIFICATION_DIRECTION) + +_CAPABILITYSPECIFICATION_PUSHNOTIFICATION = _descriptor.EnumDescriptor( + name='PushNotification', + full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.PushNotification', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DISABLED', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ENABLED', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ENABLED_HIGH_FREQUENCY', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=591, + serialized_end=664, +) +_sym_db.RegisterEnumDescriptor(_CAPABILITYSPECIFICATION_PUSHNOTIFICATION) + + +_CAPABILITYSPECIFICATION_CAPABILITY = _descriptor.Descriptor( + name='Capability', + full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.Capability', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.Capability.technical_message_type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='direction', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.Capability.direction', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=400, + serialized_end=535, +) + +_CAPABILITYSPECIFICATION = _descriptor.Descriptor( + name='CapabilitySpecification', + full_name='agrirouter.request.payload.endpoint.CapabilitySpecification', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='capabilities', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.capabilities', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='app_certification_id', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.app_certification_id', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='app_certification_version_id', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.app_certification_version_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enable_push_notifications', full_name='agrirouter.request.payload.endpoint.CapabilitySpecification.enable_push_notifications', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_CAPABILITYSPECIFICATION_CAPABILITY, ], + enum_types=[ + _CAPABILITYSPECIFICATION_DIRECTION, + _CAPABILITYSPECIFICATION_PUSHNOTIFICATION, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=95, + serialized_end=664, +) + +_CAPABILITYSPECIFICATION_CAPABILITY.fields_by_name['direction'].enum_type = _CAPABILITYSPECIFICATION_DIRECTION +_CAPABILITYSPECIFICATION_CAPABILITY.containing_type = _CAPABILITYSPECIFICATION +_CAPABILITYSPECIFICATION.fields_by_name['capabilities'].message_type = _CAPABILITYSPECIFICATION_CAPABILITY +_CAPABILITYSPECIFICATION.fields_by_name['enable_push_notifications'].enum_type = _CAPABILITYSPECIFICATION_PUSHNOTIFICATION +_CAPABILITYSPECIFICATION_DIRECTION.containing_type = _CAPABILITYSPECIFICATION +_CAPABILITYSPECIFICATION_PUSHNOTIFICATION.containing_type = _CAPABILITYSPECIFICATION +DESCRIPTOR.message_types_by_name['CapabilitySpecification'] = _CAPABILITYSPECIFICATION +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +CapabilitySpecification = _reflection.GeneratedProtocolMessageType('CapabilitySpecification', (_message.Message,), { + + 'Capability' : _reflection.GeneratedProtocolMessageType('Capability', (_message.Message,), { + 'DESCRIPTOR' : _CAPABILITYSPECIFICATION_CAPABILITY, + '__module__' : 'messaging.request.payload.endpoint.capabilities_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.payload.endpoint.CapabilitySpecification.Capability) + }) + , + 'DESCRIPTOR' : _CAPABILITYSPECIFICATION, + '__module__' : 'messaging.request.payload.endpoint.capabilities_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.payload.endpoint.CapabilitySpecification) + }) +_sym_db.RegisterMessage(CapabilitySpecification) +_sym_db.RegisterMessage(CapabilitySpecification.Capability) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/request/payload/endpoint/subscription_pb2.py b/agrirouter/generated/messaging/request/payload/endpoint/subscription_pb2.py new file mode 100644 index 00000000..fa456a6f --- /dev/null +++ b/agrirouter/generated/messaging/request/payload/endpoint/subscription_pb2.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/request/payload/endpoint/subscription.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/request/payload/endpoint/subscription.proto', + package='agrirouter.request.payload.endpoint', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n5messaging/request/payload/endpoint/subscription.proto\x12#agrirouter.request.payload.endpoint\"\xdd\x01\n\x0cSubscription\x12n\n\x17technical_message_types\x18\x01 \x03(\x0b\x32M.agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem\x1a]\n\x1bMessageTypeSubscriptionItem\x12\x1e\n\x16technical_message_type\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x64is\x18\x02 \x03(\r\x12\x10\n\x08position\x18\x03 \x01(\x08\x62\x06proto3' +) + + + + +_SUBSCRIPTION_MESSAGETYPESUBSCRIPTIONITEM = _descriptor.Descriptor( + name='MessageTypeSubscriptionItem', + full_name='agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem.technical_message_type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ddis', full_name='agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem.ddis', index=1, + number=2, type=13, cpp_type=3, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='position', full_name='agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem.position', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=223, + serialized_end=316, +) + +_SUBSCRIPTION = _descriptor.Descriptor( + name='Subscription', + full_name='agrirouter.request.payload.endpoint.Subscription', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_types', full_name='agrirouter.request.payload.endpoint.Subscription.technical_message_types', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_SUBSCRIPTION_MESSAGETYPESUBSCRIPTIONITEM, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=95, + serialized_end=316, +) + +_SUBSCRIPTION_MESSAGETYPESUBSCRIPTIONITEM.containing_type = _SUBSCRIPTION +_SUBSCRIPTION.fields_by_name['technical_message_types'].message_type = _SUBSCRIPTION_MESSAGETYPESUBSCRIPTIONITEM +DESCRIPTOR.message_types_by_name['Subscription'] = _SUBSCRIPTION +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Subscription = _reflection.GeneratedProtocolMessageType('Subscription', (_message.Message,), { + + 'MessageTypeSubscriptionItem' : _reflection.GeneratedProtocolMessageType('MessageTypeSubscriptionItem', (_message.Message,), { + 'DESCRIPTOR' : _SUBSCRIPTION_MESSAGETYPESUBSCRIPTIONITEM, + '__module__' : 'messaging.request.payload.endpoint.subscription_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.payload.endpoint.Subscription.MessageTypeSubscriptionItem) + }) + , + 'DESCRIPTOR' : _SUBSCRIPTION, + '__module__' : 'messaging.request.payload.endpoint.subscription_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.payload.endpoint.Subscription) + }) +_sym_db.RegisterMessage(Subscription) +_sym_db.RegisterMessage(Subscription.MessageTypeSubscriptionItem) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/request/payload/feed/feed_requests_pb2.py b/agrirouter/generated/messaging/request/payload/feed/feed_requests_pb2.py new file mode 100644 index 00000000..54c4b0df --- /dev/null +++ b/agrirouter/generated/messaging/request/payload/feed/feed_requests_pb2.py @@ -0,0 +1,231 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/request/payload/feed/feed-requests.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/request/payload/feed/feed-requests.proto', + package='agrirouter.feed.request', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n2messaging/request/payload/feed/feed-requests.proto\x12\x17\x61grirouter.feed.request\x1a\x1fgoogle/protobuf/timestamp.proto\"l\n\x0eValidityPeriod\x12-\n\tsent_from\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x07sent_to\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"v\n\x0cMessageQuery\x12\x13\n\x0bmessage_ids\x18\x01 \x03(\t\x12\x0f\n\x07senders\x18\x02 \x03(\t\x12@\n\x0fvalidity_period\x18\x03 \x01(\x0b\x32\'.agrirouter.feed.request.ValidityPeriod\"%\n\x0eMessageConfirm\x12\x13\n\x0bmessage_ids\x18\x01 \x03(\t\"w\n\rMessageDelete\x12\x13\n\x0bmessage_ids\x18\x01 \x03(\t\x12\x0f\n\x07senders\x18\x02 \x03(\t\x12@\n\x0fvalidity_period\x18\x03 \x01(\x0b\x32\'.agrirouter.feed.request.ValidityPeriodb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) + + + + +_VALIDITYPERIOD = _descriptor.Descriptor( + name='ValidityPeriod', + full_name='agrirouter.feed.request.ValidityPeriod', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='sent_from', full_name='agrirouter.feed.request.ValidityPeriod.sent_from', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sent_to', full_name='agrirouter.feed.request.ValidityPeriod.sent_to', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=112, + serialized_end=220, +) + + +_MESSAGEQUERY = _descriptor.Descriptor( + name='MessageQuery', + full_name='agrirouter.feed.request.MessageQuery', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message_ids', full_name='agrirouter.feed.request.MessageQuery.message_ids', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='senders', full_name='agrirouter.feed.request.MessageQuery.senders', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='validity_period', full_name='agrirouter.feed.request.MessageQuery.validity_period', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=222, + serialized_end=340, +) + + +_MESSAGECONFIRM = _descriptor.Descriptor( + name='MessageConfirm', + full_name='agrirouter.feed.request.MessageConfirm', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message_ids', full_name='agrirouter.feed.request.MessageConfirm.message_ids', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=342, + serialized_end=379, +) + + +_MESSAGEDELETE = _descriptor.Descriptor( + name='MessageDelete', + full_name='agrirouter.feed.request.MessageDelete', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message_ids', full_name='agrirouter.feed.request.MessageDelete.message_ids', index=0, + number=1, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='senders', full_name='agrirouter.feed.request.MessageDelete.senders', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='validity_period', full_name='agrirouter.feed.request.MessageDelete.validity_period', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=381, + serialized_end=500, +) + +_VALIDITYPERIOD.fields_by_name['sent_from'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_VALIDITYPERIOD.fields_by_name['sent_to'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_MESSAGEQUERY.fields_by_name['validity_period'].message_type = _VALIDITYPERIOD +_MESSAGEDELETE.fields_by_name['validity_period'].message_type = _VALIDITYPERIOD +DESCRIPTOR.message_types_by_name['ValidityPeriod'] = _VALIDITYPERIOD +DESCRIPTOR.message_types_by_name['MessageQuery'] = _MESSAGEQUERY +DESCRIPTOR.message_types_by_name['MessageConfirm'] = _MESSAGECONFIRM +DESCRIPTOR.message_types_by_name['MessageDelete'] = _MESSAGEDELETE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ValidityPeriod = _reflection.GeneratedProtocolMessageType('ValidityPeriod', (_message.Message,), { + 'DESCRIPTOR' : _VALIDITYPERIOD, + '__module__' : 'messaging.request.payload.feed.feed_requests_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.request.ValidityPeriod) + }) +_sym_db.RegisterMessage(ValidityPeriod) + +MessageQuery = _reflection.GeneratedProtocolMessageType('MessageQuery', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGEQUERY, + '__module__' : 'messaging.request.payload.feed.feed_requests_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.request.MessageQuery) + }) +_sym_db.RegisterMessage(MessageQuery) + +MessageConfirm = _reflection.GeneratedProtocolMessageType('MessageConfirm', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGECONFIRM, + '__module__' : 'messaging.request.payload.feed.feed_requests_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.request.MessageConfirm) + }) +_sym_db.RegisterMessage(MessageConfirm) + +MessageDelete = _reflection.GeneratedProtocolMessageType('MessageDelete', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGEDELETE, + '__module__' : 'messaging.request.payload.feed.feed_requests_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.request.MessageDelete) + }) +_sym_db.RegisterMessage(MessageDelete) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/request/request_pb2.py b/agrirouter/generated/messaging/request/request_pb2.py new file mode 100644 index 00000000..b193bf57 --- /dev/null +++ b/agrirouter/generated/messaging/request/request_pb2.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/request/request.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from agrirouter.generated.commons import chunk_pb2 as commons_dot_chunk__pb2 +from agrirouter.generated.commons import message_pb2 as commons_dot_message__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/request/request.proto', + package='agrirouter.request', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x1fmessaging/request/request.proto\x12\x12\x61grirouter.request\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x13\x63ommons/chunk.proto\x1a\x15\x63ommons/message.proto\"\xaf\x03\n\x0fRequestEnvelope\x12\x1e\n\x16\x61pplication_message_id\x18\x01 \x01(\t\x12\"\n\x1a\x61pplication_message_seq_no\x18\x02 \x01(\x03\x12\x1e\n\x16technical_message_type\x18\x03 \x01(\t\x12\x1b\n\x13team_set_context_id\x18\x04 \x01(\t\x12\x36\n\x04mode\x18\x05 \x01(\x0e\x32(.agrirouter.request.RequestEnvelope.Mode\x12\x12\n\nrecipients\x18\x06 \x03(\t\x12\x36\n\nchunk_info\x18\x07 \x01(\x0b\x32\".agrirouter.commons.ChunkComponent\x12-\n\ttimestamp\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\x08metadata\x18\t \x01(\x0b\x32\x1c.agrirouter.commons.Metadata\"8\n\x04Mode\x12\n\n\x06\x44IRECT\x10\x00\x12\x0b\n\x07PUBLISH\x10\x01\x12\x17\n\x13PUBLISH_WITH_DIRECT\x10\x02\">\n\x15RequestPayloadWrapper\x12%\n\x07\x64\x65tails\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Anyb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,commons_dot_chunk__pb2.DESCRIPTOR,commons_dot_message__pb2.DESCRIPTOR,]) + + + +_REQUESTENVELOPE_MODE = _descriptor.EnumDescriptor( + name='Mode', + full_name='agrirouter.request.RequestEnvelope.Mode', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DIRECT', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PUBLISH', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PUBLISH_WITH_DIRECT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=535, + serialized_end=591, +) +_sym_db.RegisterEnumDescriptor(_REQUESTENVELOPE_MODE) + + +_REQUESTENVELOPE = _descriptor.Descriptor( + name='RequestEnvelope', + full_name='agrirouter.request.RequestEnvelope', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='application_message_id', full_name='agrirouter.request.RequestEnvelope.application_message_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='application_message_seq_no', full_name='agrirouter.request.RequestEnvelope.application_message_seq_no', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.request.RequestEnvelope.technical_message_type', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='team_set_context_id', full_name='agrirouter.request.RequestEnvelope.team_set_context_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='mode', full_name='agrirouter.request.RequestEnvelope.mode', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='recipients', full_name='agrirouter.request.RequestEnvelope.recipients', index=5, + number=6, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='chunk_info', full_name='agrirouter.request.RequestEnvelope.chunk_info', index=6, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='timestamp', full_name='agrirouter.request.RequestEnvelope.timestamp', index=7, + number=8, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metadata', full_name='agrirouter.request.RequestEnvelope.metadata', index=8, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _REQUESTENVELOPE_MODE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=160, + serialized_end=591, +) + + +_REQUESTPAYLOADWRAPPER = _descriptor.Descriptor( + name='RequestPayloadWrapper', + full_name='agrirouter.request.RequestPayloadWrapper', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='details', full_name='agrirouter.request.RequestPayloadWrapper.details', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=593, + serialized_end=655, +) + +_REQUESTENVELOPE.fields_by_name['mode'].enum_type = _REQUESTENVELOPE_MODE +_REQUESTENVELOPE.fields_by_name['chunk_info'].message_type = commons_dot_chunk__pb2._CHUNKCOMPONENT +_REQUESTENVELOPE.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_REQUESTENVELOPE.fields_by_name['metadata'].message_type = commons_dot_message__pb2._METADATA +_REQUESTENVELOPE_MODE.containing_type = _REQUESTENVELOPE +_REQUESTPAYLOADWRAPPER.fields_by_name['details'].message_type = google_dot_protobuf_dot_any__pb2._ANY +DESCRIPTOR.message_types_by_name['RequestEnvelope'] = _REQUESTENVELOPE +DESCRIPTOR.message_types_by_name['RequestPayloadWrapper'] = _REQUESTPAYLOADWRAPPER +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +RequestEnvelope = _reflection.GeneratedProtocolMessageType('RequestEnvelope', (_message.Message,), { + 'DESCRIPTOR' : _REQUESTENVELOPE, + '__module__' : 'messaging.request.request_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.RequestEnvelope) + }) +_sym_db.RegisterMessage(RequestEnvelope) + +RequestPayloadWrapper = _reflection.GeneratedProtocolMessageType('RequestPayloadWrapper', (_message.Message,), { + 'DESCRIPTOR' : _REQUESTPAYLOADWRAPPER, + '__module__' : 'messaging.request.request_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.request.RequestPayloadWrapper) + }) +_sym_db.RegisterMessage(RequestPayloadWrapper) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/response/payload/account/endpoints_pb2.py b/agrirouter/generated/messaging/response/payload/account/endpoints_pb2.py new file mode 100644 index 00000000..d0f870b5 --- /dev/null +++ b/agrirouter/generated/messaging/response/payload/account/endpoints_pb2.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/response/payload/account/endpoints.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/response/payload/account/endpoints.proto', + package='agrirouter.response.payload.account', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n2messaging/response/payload/account/endpoints.proto\x12#agrirouter.response.payload.account\"\x82\x04\n\x15ListEndpointsResponse\x12V\n\tendpoints\x18\x01 \x03(\x0b\x32\x43.agrirouter.response.payload.account.ListEndpointsResponse.Endpoint\x1a\x86\x01\n\x0bMessageType\x12\x1e\n\x16technical_message_type\x18\x01 \x01(\t\x12W\n\tdirection\x18\x02 \x01(\x0e\x32\x44.agrirouter.response.payload.account.ListEndpointsResponse.Direction\x1a\xd1\x01\n\x08\x45ndpoint\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x15\n\rendpoint_name\x18\x02 \x01(\t\x12\x15\n\rendpoint_type\x18\x03 \x01(\t\x12\x0e\n\x06status\x18\x04 \x01(\t\x12]\n\rmessage_types\x18\x05 \x03(\x0b\x32\x46.agrirouter.response.payload.account.ListEndpointsResponse.MessageType\x12\x13\n\x0b\x65xternal_id\x18\x06 \x01(\t\"4\n\tDirection\x12\x08\n\x04SEND\x10\x00\x12\x0b\n\x07RECEIVE\x10\x01\x12\x10\n\x0cSEND_RECEIVE\x10\x02\x62\x06proto3' +) + + + +_LISTENDPOINTSRESPONSE_DIRECTION = _descriptor.EnumDescriptor( + name='Direction', + full_name='agrirouter.response.payload.account.ListEndpointsResponse.Direction', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='SEND', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RECEIVE', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SEND_RECEIVE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=554, + serialized_end=606, +) +_sym_db.RegisterEnumDescriptor(_LISTENDPOINTSRESPONSE_DIRECTION) + + +_LISTENDPOINTSRESPONSE_MESSAGETYPE = _descriptor.Descriptor( + name='MessageType', + full_name='agrirouter.response.payload.account.ListEndpointsResponse.MessageType', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.response.payload.account.ListEndpointsResponse.MessageType.technical_message_type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='direction', full_name='agrirouter.response.payload.account.ListEndpointsResponse.MessageType.direction', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=206, + serialized_end=340, +) + +_LISTENDPOINTSRESPONSE_ENDPOINT = _descriptor.Descriptor( + name='Endpoint', + full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='endpoint_id', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.endpoint_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='endpoint_name', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.endpoint_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='endpoint_type', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.endpoint_type', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='status', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.status', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_types', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.message_types', index=4, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='external_id', full_name='agrirouter.response.payload.account.ListEndpointsResponse.Endpoint.external_id', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=343, + serialized_end=552, +) + +_LISTENDPOINTSRESPONSE = _descriptor.Descriptor( + name='ListEndpointsResponse', + full_name='agrirouter.response.payload.account.ListEndpointsResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='endpoints', full_name='agrirouter.response.payload.account.ListEndpointsResponse.endpoints', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_LISTENDPOINTSRESPONSE_MESSAGETYPE, _LISTENDPOINTSRESPONSE_ENDPOINT, ], + enum_types=[ + _LISTENDPOINTSRESPONSE_DIRECTION, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=92, + serialized_end=606, +) + +_LISTENDPOINTSRESPONSE_MESSAGETYPE.fields_by_name['direction'].enum_type = _LISTENDPOINTSRESPONSE_DIRECTION +_LISTENDPOINTSRESPONSE_MESSAGETYPE.containing_type = _LISTENDPOINTSRESPONSE +_LISTENDPOINTSRESPONSE_ENDPOINT.fields_by_name['message_types'].message_type = _LISTENDPOINTSRESPONSE_MESSAGETYPE +_LISTENDPOINTSRESPONSE_ENDPOINT.containing_type = _LISTENDPOINTSRESPONSE +_LISTENDPOINTSRESPONSE.fields_by_name['endpoints'].message_type = _LISTENDPOINTSRESPONSE_ENDPOINT +_LISTENDPOINTSRESPONSE_DIRECTION.containing_type = _LISTENDPOINTSRESPONSE +DESCRIPTOR.message_types_by_name['ListEndpointsResponse'] = _LISTENDPOINTSRESPONSE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ListEndpointsResponse = _reflection.GeneratedProtocolMessageType('ListEndpointsResponse', (_message.Message,), { + + 'MessageType' : _reflection.GeneratedProtocolMessageType('MessageType', (_message.Message,), { + 'DESCRIPTOR' : _LISTENDPOINTSRESPONSE_MESSAGETYPE, + '__module__' : 'messaging.response.payload.account.endpoints_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.payload.account.ListEndpointsResponse.MessageType) + }) + , + + 'Endpoint' : _reflection.GeneratedProtocolMessageType('Endpoint', (_message.Message,), { + 'DESCRIPTOR' : _LISTENDPOINTSRESPONSE_ENDPOINT, + '__module__' : 'messaging.response.payload.account.endpoints_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.payload.account.ListEndpointsResponse.Endpoint) + }) + , + 'DESCRIPTOR' : _LISTENDPOINTSRESPONSE, + '__module__' : 'messaging.response.payload.account.endpoints_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.payload.account.ListEndpointsResponse) + }) +_sym_db.RegisterMessage(ListEndpointsResponse) +_sym_db.RegisterMessage(ListEndpointsResponse.MessageType) +_sym_db.RegisterMessage(ListEndpointsResponse.Endpoint) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/response/payload/endpoint/capability_pb2.py b/agrirouter/generated/messaging/response/payload/endpoint/capability_pb2.py new file mode 100644 index 00000000..cea65312 --- /dev/null +++ b/agrirouter/generated/messaging/response/payload/endpoint/capability_pb2.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/response/payload/endpoint/capability.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/response/payload/endpoint/capability.proto', + package='agrirouter.response.payload.endpoint', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n4messaging/response/payload/endpoint/capability.proto\x12$agrirouter.response.payload.endpoint\"\xc5\x01\n\x12\x43\x61pabilityResponse\x12\x1e\n\x16\x61pplication_message_id\x18\x01 \x01(\t\x12V\n\nrecipients\x18\x02 \x03(\x0b\x32\x42.agrirouter.response.payload.endpoint.CapabilityResponse.Recipient\x1a\x37\n\tRecipient\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x16technical_message_type\x18\x02 \x03(\tb\x06proto3' +) + + + + +_CAPABILITYRESPONSE_RECIPIENT = _descriptor.Descriptor( + name='Recipient', + full_name='agrirouter.response.payload.endpoint.CapabilityResponse.Recipient', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='agrirouter.response.payload.endpoint.CapabilityResponse.Recipient.id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.response.payload.endpoint.CapabilityResponse.Recipient.technical_message_type', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=237, + serialized_end=292, +) + +_CAPABILITYRESPONSE = _descriptor.Descriptor( + name='CapabilityResponse', + full_name='agrirouter.response.payload.endpoint.CapabilityResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='application_message_id', full_name='agrirouter.response.payload.endpoint.CapabilityResponse.application_message_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='recipients', full_name='agrirouter.response.payload.endpoint.CapabilityResponse.recipients', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_CAPABILITYRESPONSE_RECIPIENT, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=95, + serialized_end=292, +) + +_CAPABILITYRESPONSE_RECIPIENT.containing_type = _CAPABILITYRESPONSE +_CAPABILITYRESPONSE.fields_by_name['recipients'].message_type = _CAPABILITYRESPONSE_RECIPIENT +DESCRIPTOR.message_types_by_name['CapabilityResponse'] = _CAPABILITYRESPONSE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +CapabilityResponse = _reflection.GeneratedProtocolMessageType('CapabilityResponse', (_message.Message,), { + + 'Recipient' : _reflection.GeneratedProtocolMessageType('Recipient', (_message.Message,), { + 'DESCRIPTOR' : _CAPABILITYRESPONSE_RECIPIENT, + '__module__' : 'messaging.response.payload.endpoint.capability_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.payload.endpoint.CapabilityResponse.Recipient) + }) + , + 'DESCRIPTOR' : _CAPABILITYRESPONSE, + '__module__' : 'messaging.response.payload.endpoint.capability_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.payload.endpoint.CapabilityResponse) + }) +_sym_db.RegisterMessage(CapabilityResponse) +_sym_db.RegisterMessage(CapabilityResponse.Recipient) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/response/payload/feed/feed_response_pb2.py b/agrirouter/generated/messaging/response/payload/feed/feed_response_pb2.py new file mode 100644 index 00000000..a193a2ee --- /dev/null +++ b/agrirouter/generated/messaging/response/payload/feed/feed_response_pb2.py @@ -0,0 +1,710 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/response/payload/feed/feed-response.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from agrirouter.generated.commons import message_pb2 as commons_dot_message__pb2 +from agrirouter.generated.commons import chunk_pb2 as commons_dot_chunk__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/response/payload/feed/feed-response.proto', + package='agrirouter.feed.response', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n3messaging/response/payload/feed/feed-response.proto\x12\x18\x61grirouter.feed.response\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19google/protobuf/any.proto\x1a\x15\x63ommons/message.proto\x1a\x13\x63ommons/chunk.proto\"%\n\x04Page\x12\x0e\n\x06number\x18\x01 \x01(\x05\x12\r\n\x05total\x18\x02 \x01(\x05\"N\n\x0cQueryMetrics\x12\x1f\n\x17total_messages_in_query\x18\x01 \x01(\x05\x12\x1d\n\x15max_count_restriction\x18\x02 \x01(\x05\"\xe8\x05\n\x13HeaderQueryResponse\x12=\n\rquery_metrics\x18\x01 \x01(\x0b\x32&.agrirouter.feed.response.QueryMetrics\x12,\n\x04page\x18\x02 \x01(\x0b\x32\x1e.agrirouter.feed.response.Page\x12:\n\x0e\x63hunk_contexts\x18\x03 \x03(\x0b\x32\".agrirouter.commons.ChunkComponent\x12@\n\x04\x66\x65\x65\x64\x18\x04 \x03(\x0b\x32\x32.agrirouter.feed.response.HeaderQueryResponse.Feed\x12\x1f\n\x13pending_message_ids\x18\x05 \x03(\tB\x02\x18\x01\x1a\xcd\x02\n\x06Header\x12\x12\n\nmessage_id\x18\x01 \x01(\t\x12\x1e\n\x16technical_message_type\x18\x02 \x01(\t\x12\x1b\n\x13team_set_context_id\x18\x03 \x01(\t\x12\x18\n\x10\x63hunk_context_id\x18\x04 \x01(\t\x12\x14\n\x0cpayload_size\x18\x05 \x01(\x03\x12\x32\n\x0esent_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x17\n\x0fsequence_number\x18\x07 \x01(\x03\x12\x15\n\rcurrent_chunk\x18\x08 \x01(\x03\x12.\n\ncreated_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\x08metadata\x18\n \x01(\x0b\x32\x1c.agrirouter.commons.Metadata\x1au\n\x04\x46\x65\x65\x64\x12\x11\n\tsender_id\x18\x01 \x01(\t\x12\x13\n\x0breceiver_id\x18\x02 \x01(\t\x12\x45\n\x07headers\x18\x03 \x03(\x0b\x32\x34.agrirouter.feed.response.HeaderQueryResponse.Header\"\xd0\x05\n\x14MessageQueryResponse\x12=\n\rquery_metrics\x18\x01 \x01(\x0b\x32&.agrirouter.feed.response.QueryMetrics\x12,\n\x04page\x18\x02 \x01(\x0b\x32\x1e.agrirouter.feed.response.Page\x12L\n\x08messages\x18\x03 \x03(\x0b\x32:.agrirouter.feed.response.MessageQueryResponse.FeedMessage\x1a\xff\x02\n\x06Header\x12\x13\n\x0breceiver_id\x18\x01 \x01(\t\x12\x1e\n\x16technical_message_type\x18\x02 \x01(\t\x12\x1b\n\x13team_set_context_id\x18\x03 \x01(\t\x12\x39\n\rchunk_context\x18\x04 \x01(\x0b\x32\".agrirouter.commons.ChunkComponent\x12\x14\n\x0cpayload_size\x18\x05 \x01(\x03\x12\x32\n\x0esent_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x17\n\x0fsequence_number\x18\x07 \x01(\x03\x12\x11\n\tsender_id\x18\x08 \x01(\t\x12.\n\ncreated_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nmessage_id\x18\n \x01(\t\x12.\n\x08metadata\x18\x0b \x01(\x0b\x32\x1c.agrirouter.commons.Metadata\x1a{\n\x0b\x46\x65\x65\x64Message\x12\x45\n\x06header\x18\x01 \x01(\x0b\x32\x35.agrirouter.feed.response.MessageQueryResponse.Header\x12%\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\"\x96\x03\n\x1a\x46\x61iledMessageQueryResponse\x12=\n\rquery_metrics\x18\x01 \x01(\x0b\x32&.agrirouter.feed.response.QueryMetrics\x12,\n\x04page\x18\x02 \x01(\x0b\x32\x1e.agrirouter.feed.response.Page\x12K\n\x06header\x18\x03 \x01(\x0b\x32;.agrirouter.feed.response.FailedMessageQueryResponse.Header\x12,\n\x07reasons\x18\x04 \x03(\x0b\x32\x1b.agrirouter.commons.Message\x1a\x8f\x01\n\x06Header\x12\x1e\n\x16technical_message_type\x18\x01 \x01(\t\x12\x1b\n\x13team_set_context_id\x18\x02 \x01(\t\x12\x14\n\x0cpayload_size\x18\x03 \x01(\x03\x12\x32\n\x0esent_timestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestampb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_any__pb2.DESCRIPTOR,commons_dot_message__pb2.DESCRIPTOR,commons_dot_chunk__pb2.DESCRIPTOR,]) + + + + +_PAGE = _descriptor.Descriptor( + name='Page', + full_name='agrirouter.feed.response.Page', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='number', full_name='agrirouter.feed.response.Page.number', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='total', full_name='agrirouter.feed.response.Page.total', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=185, + serialized_end=222, +) + + +_QUERYMETRICS = _descriptor.Descriptor( + name='QueryMetrics', + full_name='agrirouter.feed.response.QueryMetrics', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='total_messages_in_query', full_name='agrirouter.feed.response.QueryMetrics.total_messages_in_query', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='max_count_restriction', full_name='agrirouter.feed.response.QueryMetrics.max_count_restriction', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=224, + serialized_end=302, +) + + +_HEADERQUERYRESPONSE_HEADER = _descriptor.Descriptor( + name='Header', + full_name='agrirouter.feed.response.HeaderQueryResponse.Header', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message_id', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.message_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.technical_message_type', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='team_set_context_id', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.team_set_context_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='chunk_context_id', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.chunk_context_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='payload_size', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.payload_size', index=4, + number=5, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sent_timestamp', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.sent_timestamp', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sequence_number', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.sequence_number', index=6, + number=7, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='current_chunk', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.current_chunk', index=7, + number=8, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='created_at', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.created_at', index=8, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metadata', full_name='agrirouter.feed.response.HeaderQueryResponse.Header.metadata', index=9, + number=10, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=597, + serialized_end=930, +) + +_HEADERQUERYRESPONSE_FEED = _descriptor.Descriptor( + name='Feed', + full_name='agrirouter.feed.response.HeaderQueryResponse.Feed', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='sender_id', full_name='agrirouter.feed.response.HeaderQueryResponse.Feed.sender_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='receiver_id', full_name='agrirouter.feed.response.HeaderQueryResponse.Feed.receiver_id', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='headers', full_name='agrirouter.feed.response.HeaderQueryResponse.Feed.headers', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=932, + serialized_end=1049, +) + +_HEADERQUERYRESPONSE = _descriptor.Descriptor( + name='HeaderQueryResponse', + full_name='agrirouter.feed.response.HeaderQueryResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='query_metrics', full_name='agrirouter.feed.response.HeaderQueryResponse.query_metrics', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='page', full_name='agrirouter.feed.response.HeaderQueryResponse.page', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='chunk_contexts', full_name='agrirouter.feed.response.HeaderQueryResponse.chunk_contexts', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='feed', full_name='agrirouter.feed.response.HeaderQueryResponse.feed', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='pending_message_ids', full_name='agrirouter.feed.response.HeaderQueryResponse.pending_message_ids', index=4, + number=5, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\030\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_HEADERQUERYRESPONSE_HEADER, _HEADERQUERYRESPONSE_FEED, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=305, + serialized_end=1049, +) + + +_MESSAGEQUERYRESPONSE_HEADER = _descriptor.Descriptor( + name='Header', + full_name='agrirouter.feed.response.MessageQueryResponse.Header', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='receiver_id', full_name='agrirouter.feed.response.MessageQueryResponse.Header.receiver_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.feed.response.MessageQueryResponse.Header.technical_message_type', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='team_set_context_id', full_name='agrirouter.feed.response.MessageQueryResponse.Header.team_set_context_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='chunk_context', full_name='agrirouter.feed.response.MessageQueryResponse.Header.chunk_context', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='payload_size', full_name='agrirouter.feed.response.MessageQueryResponse.Header.payload_size', index=4, + number=5, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sent_timestamp', full_name='agrirouter.feed.response.MessageQueryResponse.Header.sent_timestamp', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sequence_number', full_name='agrirouter.feed.response.MessageQueryResponse.Header.sequence_number', index=6, + number=7, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sender_id', full_name='agrirouter.feed.response.MessageQueryResponse.Header.sender_id', index=7, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='created_at', full_name='agrirouter.feed.response.MessageQueryResponse.Header.created_at', index=8, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_id', full_name='agrirouter.feed.response.MessageQueryResponse.Header.message_id', index=9, + number=10, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metadata', full_name='agrirouter.feed.response.MessageQueryResponse.Header.metadata', index=10, + number=11, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1264, + serialized_end=1647, +) + +_MESSAGEQUERYRESPONSE_FEEDMESSAGE = _descriptor.Descriptor( + name='FeedMessage', + full_name='agrirouter.feed.response.MessageQueryResponse.FeedMessage', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='header', full_name='agrirouter.feed.response.MessageQueryResponse.FeedMessage.header', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='content', full_name='agrirouter.feed.response.MessageQueryResponse.FeedMessage.content', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1649, + serialized_end=1772, +) + +_MESSAGEQUERYRESPONSE = _descriptor.Descriptor( + name='MessageQueryResponse', + full_name='agrirouter.feed.response.MessageQueryResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='query_metrics', full_name='agrirouter.feed.response.MessageQueryResponse.query_metrics', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='page', full_name='agrirouter.feed.response.MessageQueryResponse.page', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='messages', full_name='agrirouter.feed.response.MessageQueryResponse.messages', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_MESSAGEQUERYRESPONSE_HEADER, _MESSAGEQUERYRESPONSE_FEEDMESSAGE, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1052, + serialized_end=1772, +) + + +_FAILEDMESSAGEQUERYRESPONSE_HEADER = _descriptor.Descriptor( + name='Header', + full_name='agrirouter.feed.response.FailedMessageQueryResponse.Header', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.feed.response.FailedMessageQueryResponse.Header.technical_message_type', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='team_set_context_id', full_name='agrirouter.feed.response.FailedMessageQueryResponse.Header.team_set_context_id', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='payload_size', full_name='agrirouter.feed.response.FailedMessageQueryResponse.Header.payload_size', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sent_timestamp', full_name='agrirouter.feed.response.FailedMessageQueryResponse.Header.sent_timestamp', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2038, + serialized_end=2181, +) + +_FAILEDMESSAGEQUERYRESPONSE = _descriptor.Descriptor( + name='FailedMessageQueryResponse', + full_name='agrirouter.feed.response.FailedMessageQueryResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='query_metrics', full_name='agrirouter.feed.response.FailedMessageQueryResponse.query_metrics', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='page', full_name='agrirouter.feed.response.FailedMessageQueryResponse.page', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='header', full_name='agrirouter.feed.response.FailedMessageQueryResponse.header', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reasons', full_name='agrirouter.feed.response.FailedMessageQueryResponse.reasons', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_FAILEDMESSAGEQUERYRESPONSE_HEADER, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1775, + serialized_end=2181, +) + +_HEADERQUERYRESPONSE_HEADER.fields_by_name['sent_timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_HEADERQUERYRESPONSE_HEADER.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_HEADERQUERYRESPONSE_HEADER.fields_by_name['metadata'].message_type = commons_dot_message__pb2._METADATA +_HEADERQUERYRESPONSE_HEADER.containing_type = _HEADERQUERYRESPONSE +_HEADERQUERYRESPONSE_FEED.fields_by_name['headers'].message_type = _HEADERQUERYRESPONSE_HEADER +_HEADERQUERYRESPONSE_FEED.containing_type = _HEADERQUERYRESPONSE +_HEADERQUERYRESPONSE.fields_by_name['query_metrics'].message_type = _QUERYMETRICS +_HEADERQUERYRESPONSE.fields_by_name['page'].message_type = _PAGE +_HEADERQUERYRESPONSE.fields_by_name['chunk_contexts'].message_type = commons_dot_chunk__pb2._CHUNKCOMPONENT +_HEADERQUERYRESPONSE.fields_by_name['feed'].message_type = _HEADERQUERYRESPONSE_FEED +_MESSAGEQUERYRESPONSE_HEADER.fields_by_name['chunk_context'].message_type = commons_dot_chunk__pb2._CHUNKCOMPONENT +_MESSAGEQUERYRESPONSE_HEADER.fields_by_name['sent_timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_MESSAGEQUERYRESPONSE_HEADER.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_MESSAGEQUERYRESPONSE_HEADER.fields_by_name['metadata'].message_type = commons_dot_message__pb2._METADATA +_MESSAGEQUERYRESPONSE_HEADER.containing_type = _MESSAGEQUERYRESPONSE +_MESSAGEQUERYRESPONSE_FEEDMESSAGE.fields_by_name['header'].message_type = _MESSAGEQUERYRESPONSE_HEADER +_MESSAGEQUERYRESPONSE_FEEDMESSAGE.fields_by_name['content'].message_type = google_dot_protobuf_dot_any__pb2._ANY +_MESSAGEQUERYRESPONSE_FEEDMESSAGE.containing_type = _MESSAGEQUERYRESPONSE +_MESSAGEQUERYRESPONSE.fields_by_name['query_metrics'].message_type = _QUERYMETRICS +_MESSAGEQUERYRESPONSE.fields_by_name['page'].message_type = _PAGE +_MESSAGEQUERYRESPONSE.fields_by_name['messages'].message_type = _MESSAGEQUERYRESPONSE_FEEDMESSAGE +_FAILEDMESSAGEQUERYRESPONSE_HEADER.fields_by_name['sent_timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_FAILEDMESSAGEQUERYRESPONSE_HEADER.containing_type = _FAILEDMESSAGEQUERYRESPONSE +_FAILEDMESSAGEQUERYRESPONSE.fields_by_name['query_metrics'].message_type = _QUERYMETRICS +_FAILEDMESSAGEQUERYRESPONSE.fields_by_name['page'].message_type = _PAGE +_FAILEDMESSAGEQUERYRESPONSE.fields_by_name['header'].message_type = _FAILEDMESSAGEQUERYRESPONSE_HEADER +_FAILEDMESSAGEQUERYRESPONSE.fields_by_name['reasons'].message_type = commons_dot_message__pb2._MESSAGE +DESCRIPTOR.message_types_by_name['Page'] = _PAGE +DESCRIPTOR.message_types_by_name['QueryMetrics'] = _QUERYMETRICS +DESCRIPTOR.message_types_by_name['HeaderQueryResponse'] = _HEADERQUERYRESPONSE +DESCRIPTOR.message_types_by_name['MessageQueryResponse'] = _MESSAGEQUERYRESPONSE +DESCRIPTOR.message_types_by_name['FailedMessageQueryResponse'] = _FAILEDMESSAGEQUERYRESPONSE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Page = _reflection.GeneratedProtocolMessageType('Page', (_message.Message,), { + 'DESCRIPTOR' : _PAGE, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.Page) + }) +_sym_db.RegisterMessage(Page) + +QueryMetrics = _reflection.GeneratedProtocolMessageType('QueryMetrics', (_message.Message,), { + 'DESCRIPTOR' : _QUERYMETRICS, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.QueryMetrics) + }) +_sym_db.RegisterMessage(QueryMetrics) + +HeaderQueryResponse = _reflection.GeneratedProtocolMessageType('HeaderQueryResponse', (_message.Message,), { + + 'Header' : _reflection.GeneratedProtocolMessageType('Header', (_message.Message,), { + 'DESCRIPTOR' : _HEADERQUERYRESPONSE_HEADER, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.HeaderQueryResponse.Header) + }) + , + + 'Feed' : _reflection.GeneratedProtocolMessageType('Feed', (_message.Message,), { + 'DESCRIPTOR' : _HEADERQUERYRESPONSE_FEED, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.HeaderQueryResponse.Feed) + }) + , + 'DESCRIPTOR' : _HEADERQUERYRESPONSE, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.HeaderQueryResponse) + }) +_sym_db.RegisterMessage(HeaderQueryResponse) +_sym_db.RegisterMessage(HeaderQueryResponse.Header) +_sym_db.RegisterMessage(HeaderQueryResponse.Feed) + +MessageQueryResponse = _reflection.GeneratedProtocolMessageType('MessageQueryResponse', (_message.Message,), { + + 'Header' : _reflection.GeneratedProtocolMessageType('Header', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGEQUERYRESPONSE_HEADER, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.MessageQueryResponse.Header) + }) + , + + 'FeedMessage' : _reflection.GeneratedProtocolMessageType('FeedMessage', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGEQUERYRESPONSE_FEEDMESSAGE, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.MessageQueryResponse.FeedMessage) + }) + , + 'DESCRIPTOR' : _MESSAGEQUERYRESPONSE, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.MessageQueryResponse) + }) +_sym_db.RegisterMessage(MessageQueryResponse) +_sym_db.RegisterMessage(MessageQueryResponse.Header) +_sym_db.RegisterMessage(MessageQueryResponse.FeedMessage) + +FailedMessageQueryResponse = _reflection.GeneratedProtocolMessageType('FailedMessageQueryResponse', (_message.Message,), { + + 'Header' : _reflection.GeneratedProtocolMessageType('Header', (_message.Message,), { + 'DESCRIPTOR' : _FAILEDMESSAGEQUERYRESPONSE_HEADER, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.FailedMessageQueryResponse.Header) + }) + , + 'DESCRIPTOR' : _FAILEDMESSAGEQUERYRESPONSE, + '__module__' : 'messaging.response.payload.feed.feed_response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.response.FailedMessageQueryResponse) + }) +_sym_db.RegisterMessage(FailedMessageQueryResponse) +_sym_db.RegisterMessage(FailedMessageQueryResponse.Header) + + +_HEADERQUERYRESPONSE.fields_by_name['pending_message_ids']._options = None +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/response/payload/feed/push_notification_pb2.py b/agrirouter/generated/messaging/response/payload/feed/push_notification_pb2.py new file mode 100644 index 00000000..2cc8a8f0 --- /dev/null +++ b/agrirouter/generated/messaging/response/payload/feed/push_notification_pb2.py @@ -0,0 +1,239 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/response/payload/feed/push-notification.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from agrirouter.generated.commons import message_pb2 as commons_dot_message__pb2 +from agrirouter.generated.commons import chunk_pb2 as commons_dot_chunk__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/response/payload/feed/push-notification.proto', + package='agrirouter.feed.push.notification', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n7messaging/response/payload/feed/push-notification.proto\x12!agrirouter.feed.push.notification\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19google/protobuf/any.proto\x1a\x15\x63ommons/message.proto\x1a\x13\x63ommons/chunk.proto\"\xea\x04\n\x10PushNotification\x12Q\n\x08messages\x18\x01 \x03(\x0b\x32?.agrirouter.feed.push.notification.PushNotification.FeedMessage\x1a\xff\x02\n\x06Header\x12\x13\n\x0breceiver_id\x18\x01 \x01(\t\x12\x1e\n\x16technical_message_type\x18\x02 \x01(\t\x12\x1b\n\x13team_set_context_id\x18\x03 \x01(\t\x12\x39\n\rchunk_context\x18\x04 \x01(\x0b\x32\".agrirouter.commons.ChunkComponent\x12\x14\n\x0cpayload_size\x18\x05 \x01(\x03\x12\x32\n\x0esent_timestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x17\n\x0fsequence_number\x18\x07 \x01(\x03\x12\x11\n\tsender_id\x18\x08 \x01(\t\x12.\n\ncreated_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nmessage_id\x18\n \x01(\t\x12.\n\x08metadata\x18\x0b \x01(\x0b\x32\x1c.agrirouter.commons.Metadata\x1a\x80\x01\n\x0b\x46\x65\x65\x64Message\x12J\n\x06header\x18\x01 \x01(\x0b\x32:.agrirouter.feed.push.notification.PushNotification.Header\x12%\n\x07\x63ontent\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Anyb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_any__pb2.DESCRIPTOR,commons_dot_message__pb2.DESCRIPTOR,commons_dot_chunk__pb2.DESCRIPTOR,]) + + + + +_PUSHNOTIFICATION_HEADER = _descriptor.Descriptor( + name='Header', + full_name='agrirouter.feed.push.notification.PushNotification.Header', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='receiver_id', full_name='agrirouter.feed.push.notification.PushNotification.Header.receiver_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='technical_message_type', full_name='agrirouter.feed.push.notification.PushNotification.Header.technical_message_type', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='team_set_context_id', full_name='agrirouter.feed.push.notification.PushNotification.Header.team_set_context_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='chunk_context', full_name='agrirouter.feed.push.notification.PushNotification.Header.chunk_context', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='payload_size', full_name='agrirouter.feed.push.notification.PushNotification.Header.payload_size', index=4, + number=5, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sent_timestamp', full_name='agrirouter.feed.push.notification.PushNotification.Header.sent_timestamp', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sequence_number', full_name='agrirouter.feed.push.notification.PushNotification.Header.sequence_number', index=6, + number=7, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='sender_id', full_name='agrirouter.feed.push.notification.PushNotification.Header.sender_id', index=7, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='created_at', full_name='agrirouter.feed.push.notification.PushNotification.Header.created_at', index=8, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_id', full_name='agrirouter.feed.push.notification.PushNotification.Header.message_id', index=9, + number=10, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='metadata', full_name='agrirouter.feed.push.notification.PushNotification.Header.metadata', index=10, + number=11, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=303, + serialized_end=686, +) + +_PUSHNOTIFICATION_FEEDMESSAGE = _descriptor.Descriptor( + name='FeedMessage', + full_name='agrirouter.feed.push.notification.PushNotification.FeedMessage', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='header', full_name='agrirouter.feed.push.notification.PushNotification.FeedMessage.header', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='content', full_name='agrirouter.feed.push.notification.PushNotification.FeedMessage.content', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=689, + serialized_end=817, +) + +_PUSHNOTIFICATION = _descriptor.Descriptor( + name='PushNotification', + full_name='agrirouter.feed.push.notification.PushNotification', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='messages', full_name='agrirouter.feed.push.notification.PushNotification.messages', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_PUSHNOTIFICATION_HEADER, _PUSHNOTIFICATION_FEEDMESSAGE, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=199, + serialized_end=817, +) + +_PUSHNOTIFICATION_HEADER.fields_by_name['chunk_context'].message_type = commons_dot_chunk__pb2._CHUNKCOMPONENT +_PUSHNOTIFICATION_HEADER.fields_by_name['sent_timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_PUSHNOTIFICATION_HEADER.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_PUSHNOTIFICATION_HEADER.fields_by_name['metadata'].message_type = commons_dot_message__pb2._METADATA +_PUSHNOTIFICATION_HEADER.containing_type = _PUSHNOTIFICATION +_PUSHNOTIFICATION_FEEDMESSAGE.fields_by_name['header'].message_type = _PUSHNOTIFICATION_HEADER +_PUSHNOTIFICATION_FEEDMESSAGE.fields_by_name['content'].message_type = google_dot_protobuf_dot_any__pb2._ANY +_PUSHNOTIFICATION_FEEDMESSAGE.containing_type = _PUSHNOTIFICATION +_PUSHNOTIFICATION.fields_by_name['messages'].message_type = _PUSHNOTIFICATION_FEEDMESSAGE +DESCRIPTOR.message_types_by_name['PushNotification'] = _PUSHNOTIFICATION +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +PushNotification = _reflection.GeneratedProtocolMessageType('PushNotification', (_message.Message,), { + + 'Header' : _reflection.GeneratedProtocolMessageType('Header', (_message.Message,), { + 'DESCRIPTOR' : _PUSHNOTIFICATION_HEADER, + '__module__' : 'messaging.response.payload.feed.push_notification_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.push.notification.PushNotification.Header) + }) + , + + 'FeedMessage' : _reflection.GeneratedProtocolMessageType('FeedMessage', (_message.Message,), { + 'DESCRIPTOR' : _PUSHNOTIFICATION_FEEDMESSAGE, + '__module__' : 'messaging.response.payload.feed.push_notification_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.push.notification.PushNotification.FeedMessage) + }) + , + 'DESCRIPTOR' : _PUSHNOTIFICATION, + '__module__' : 'messaging.response.payload.feed.push_notification_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.feed.push.notification.PushNotification) + }) +_sym_db.RegisterMessage(PushNotification) +_sym_db.RegisterMessage(PushNotification.Header) +_sym_db.RegisterMessage(PushNotification.FeedMessage) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/messaging/response/response_pb2.py b/agrirouter/generated/messaging/response/response_pb2.py new file mode 100644 index 00000000..235e58b8 --- /dev/null +++ b/agrirouter/generated/messaging/response/response_pb2.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: messaging/response/response.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='messaging/response/response.proto', + package='agrirouter.response', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n!messaging/response/response.proto\x12\x13\x61grirouter.response\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcb\x03\n\x10ResponseEnvelope\x12\x15\n\rresponse_code\x18\x01 \x01(\x05\x12\x44\n\x04type\x18\x02 \x01(\x0e\x32\x36.agrirouter.response.ResponseEnvelope.ResponseBodyType\x12\x1e\n\x16\x61pplication_message_id\x18\x03 \x01(\t\x12\x12\n\nmessage_id\x18\x04 \x01(\t\x12-\n\ttimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xf6\x01\n\x10ResponseBodyType\x12\x0c\n\x08MESSAGES\x10\x00\x12\x07\n\x03\x41\x43K\x10\x01\x12\x15\n\x11\x41\x43K_WITH_MESSAGES\x10\x02\x12\x14\n\x10\x41\x43K_WITH_FAILURE\x10\x03\x12\x1c\n\x18\x41\x43K_FOR_FEED_HEADER_LIST\x10\x06\x12\x18\n\x14\x41\x43K_FOR_FEED_MESSAGE\x10\x07\x12\x1f\n\x1b\x41\x43K_FOR_FEED_FAILED_MESSAGE\x10\x08\x12\x15\n\x11\x45NDPOINTS_LISTING\x10\n\x12\x17\n\x13\x43LOUD_REGISTRATIONS\x10\x0b\x12\x15\n\x11PUSH_NOTIFICATION\x10\x0c\"?\n\x16ResponsePayloadWrapper\x12%\n\x07\x64\x65tails\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Anyb\x06proto3' + , + dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) + + + +_RESPONSEENVELOPE_RESPONSEBODYTYPE = _descriptor.EnumDescriptor( + name='ResponseBodyType', + full_name='agrirouter.response.ResponseEnvelope.ResponseBodyType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='MESSAGES', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK_WITH_MESSAGES', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK_WITH_FAILURE', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK_FOR_FEED_HEADER_LIST', index=4, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK_FOR_FEED_MESSAGE', index=5, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ACK_FOR_FEED_FAILED_MESSAGE', index=6, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ENDPOINTS_LISTING', index=7, number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CLOUD_REGISTRATIONS', index=8, number=11, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PUSH_NOTIFICATION', index=9, number=12, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + serialized_start=332, + serialized_end=578, +) +_sym_db.RegisterEnumDescriptor(_RESPONSEENVELOPE_RESPONSEBODYTYPE) + + +_RESPONSEENVELOPE = _descriptor.Descriptor( + name='ResponseEnvelope', + full_name='agrirouter.response.ResponseEnvelope', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='response_code', full_name='agrirouter.response.ResponseEnvelope.response_code', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='type', full_name='agrirouter.response.ResponseEnvelope.type', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='application_message_id', full_name='agrirouter.response.ResponseEnvelope.application_message_id', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_id', full_name='agrirouter.response.ResponseEnvelope.message_id', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='timestamp', full_name='agrirouter.response.ResponseEnvelope.timestamp', index=4, + number=5, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _RESPONSEENVELOPE_RESPONSEBODYTYPE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=119, + serialized_end=578, +) + + +_RESPONSEPAYLOADWRAPPER = _descriptor.Descriptor( + name='ResponsePayloadWrapper', + full_name='agrirouter.response.ResponsePayloadWrapper', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='details', full_name='agrirouter.response.ResponsePayloadWrapper.details', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=580, + serialized_end=643, +) + +_RESPONSEENVELOPE.fields_by_name['type'].enum_type = _RESPONSEENVELOPE_RESPONSEBODYTYPE +_RESPONSEENVELOPE.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_RESPONSEENVELOPE_RESPONSEBODYTYPE.containing_type = _RESPONSEENVELOPE +_RESPONSEPAYLOADWRAPPER.fields_by_name['details'].message_type = google_dot_protobuf_dot_any__pb2._ANY +DESCRIPTOR.message_types_by_name['ResponseEnvelope'] = _RESPONSEENVELOPE +DESCRIPTOR.message_types_by_name['ResponsePayloadWrapper'] = _RESPONSEPAYLOADWRAPPER +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ResponseEnvelope = _reflection.GeneratedProtocolMessageType('ResponseEnvelope', (_message.Message,), { + 'DESCRIPTOR' : _RESPONSEENVELOPE, + '__module__' : 'messaging.response.response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.ResponseEnvelope) + }) +_sym_db.RegisterMessage(ResponseEnvelope) + +ResponsePayloadWrapper = _reflection.GeneratedProtocolMessageType('ResponsePayloadWrapper', (_message.Message,), { + 'DESCRIPTOR' : _RESPONSEPAYLOADWRAPPER, + '__module__' : 'messaging.response.response_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.response.ResponsePayloadWrapper) + }) +_sym_db.RegisterMessage(ResponsePayloadWrapper) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/generated/settings/dh_settings_pb2.py b/agrirouter/generated/settings/dh_settings_pb2.py new file mode 100644 index 00000000..c40238fc --- /dev/null +++ b/agrirouter/generated/settings/dh_settings_pb2.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: settings/dh-settings.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='settings/dh-settings.proto', + package='agrirouter.message.settings', + syntax='proto3', + serialized_options=None, + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n\x1asettings/dh-settings.proto\x12\x1b\x61grirouter.message.settings\"R\n\x16\x44\x61taHubControlSettings\x12\x18\n\x10max_message_size\x18\x01 \x01(\x05\x12\x1e\n\x16max_messages_per_query\x18\x02 \x01(\x05\x62\x06proto3' +) + + + + +_DATAHUBCONTROLSETTINGS = _descriptor.Descriptor( + name='DataHubControlSettings', + full_name='agrirouter.message.settings.DataHubControlSettings', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='max_message_size', full_name='agrirouter.message.settings.DataHubControlSettings.max_message_size', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='max_messages_per_query', full_name='agrirouter.message.settings.DataHubControlSettings.max_messages_per_query', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=59, + serialized_end=141, +) + +DESCRIPTOR.message_types_by_name['DataHubControlSettings'] = _DATAHUBCONTROLSETTINGS +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +DataHubControlSettings = _reflection.GeneratedProtocolMessageType('DataHubControlSettings', (_message.Message,), { + 'DESCRIPTOR' : _DATAHUBCONTROLSETTINGS, + '__module__' : 'settings.dh_settings_pb2' + # @@protoc_insertion_point(class_scope:agrirouter.message.settings.DataHubControlSettings) + }) +_sym_db.RegisterMessage(DataHubControlSettings) + + +# @@protoc_insertion_point(module_scope) diff --git a/agrirouter/clients/__init__.py b/agrirouter/messaging/__init__.py similarity index 100% rename from agrirouter/clients/__init__.py rename to agrirouter/messaging/__init__.py diff --git a/agrirouter/messaging/certification.py b/agrirouter/messaging/certification.py new file mode 100644 index 00000000..5579b870 --- /dev/null +++ b/agrirouter/messaging/certification.py @@ -0,0 +1,23 @@ +import json +import os +import pathlib +from pathlib import Path +import tempfile + + +from agrirouter.onboarding.response import BaseOnboardingResonse + + +def create_certificate_file(onboard_response: BaseOnboardingResonse): + dir_ = tempfile.mkdtemp() + prefix = onboard_response.get_sensor_alternate_id() + data = onboard_response.get_authentication().get_certificate() + fd, path = tempfile.mkstemp(dir=dir_, prefix=prefix, text=True) + try: + with os.fdopen(fd, 'w') as tmp: + tmp.write(data) + except Exception as exc: + os.remove(path) + raise exc + + return path diff --git a/tests/__init__.py b/agrirouter/messaging/clients/__init__.py similarity index 100% rename from tests/__init__.py rename to agrirouter/messaging/clients/__init__.py diff --git a/agrirouter/messaging/clients/http.py b/agrirouter/messaging/clients/http.py new file mode 100644 index 00000000..08530c77 --- /dev/null +++ b/agrirouter/messaging/clients/http.py @@ -0,0 +1,22 @@ +class HttpClient: + + headers = {"Content-Type": "application/json"} + + def __init__(self, + on_message_callback: callable, + timeout=20 + ): + self.on_message_callback = on_message_callback + self.timeout = timeout + + def publish(self): + pass + + def subscribe(self): + pass + + def unsubscribe(self): + pass + + def _start_loop(self): + pass diff --git a/agrirouter/messaging/clients/mqtt.py b/agrirouter/messaging/clients/mqtt.py new file mode 100644 index 00000000..4e8dd555 --- /dev/null +++ b/agrirouter/messaging/clients/mqtt.py @@ -0,0 +1,138 @@ +from typing import Any, List, Tuple + +from paho.mqtt import client as mqtt_client +from paho.mqtt.client import MQTTv31, MQTTMessageInfo + + +class MqttClient: + + def __init__(self, + client_id: str = "", + on_message_callback: callable = None, + userdata: Any = None, + clean_session: bool = True + ): + # TODO: Implement on_message_callback parameter validation: + # must take params as described at https://pypi.org/project/paho-mqtt/#callbacks + + self.mqtt_client = mqtt_client.Client( + client_id=client_id, + clean_session=clean_session, + userdata=userdata, + protocol=MQTTv31, + transport="tcp" + ) + self.mqtt_client.on_message = on_message_callback if on_message_callback else self._get_on_message_callback() + self.mqtt_client.on_connect = self._get_on_connect_callback() + self.mqtt_client.on_disconnect = self._get_on_disconnect_callback() + self.mqtt_client.on_subscribe = self._get_on_subscribe_callback() + self.mqtt_client.on_unsubscribe = self._get_on_unsubscribe_callback() + + def connect(self, host: str, port: str) -> None: + self.mqtt_client.connect_async( + host=host, + port=port + ) + self.mqtt_client.loop_start() + + def disconnect(self): + self.mqtt_client.loop_stop() + self.mqtt_client.disconnect() + + def publish(self, topic, payload, qos=0) -> MQTTMessageInfo: + """ + + :param topic: str representing unique name of the topic that the message should be published on + :param payload: The actual message to send + :param qos: int representing the quality of service level to use. May be [0, 1, 2] + :return: MQTTMessageInfo + """ + message_info = self.mqtt_client.publish( + topic=topic, + payload=payload, + qos=qos + ) + return message_info + + def subscribe(self, topics: List[Tuple[str, int]]) -> tuple: + """ + + :param topics: list of tuples [(topic, qos),] containing topic to subscribe on + and desired quality of service + + topic: str representing unique name of the topic to subscribe on + qos: int representing the quality of service level to use. May be [0, 1, 2] + + Example: topics=[('my/topic/1', 0), ('my/topic/2', 1), ('my/topic/3', 2)] + + :return: tuple + """ + result, mid = self.mqtt_client.subscribe(topics) + return result, mid + + def unsubscribe(self, topics: List[str]) -> tuple: + """ + + :param topics: list of strings [topic, topic] containing topic to unsubscribe from + + topic: str representing unique name of the topic to unsubscribe from + + Example: topics=['my/topic/1', 'my/topic/2', 'my/topic/3'] + + :return: tuple + """ + result, mid = self.mqtt_client.unsubscribe(topics) + return result, mid + + @staticmethod + def _get_on_connect_callback() -> callable: + + def on_connect(client, userdata, flags, rc, properties=None): + if rc == 0: + print("Connected to MQTT Broker!") + else: + print(f"Failed to connect, return code: {rc}") + + return client, userdata, flags, rc, properties + + return on_connect + + @staticmethod + def _get_on_message_callback() -> callable: + + def on_message(client, userdata, msg): + # print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic") + + return client, userdata, msg + + return on_message + + @staticmethod + def _get_on_subscribe_callback() -> callable: + + def on_subscribe(client, userdata, mid, granted_qos, properties=None): + # print(f"Subscribed {userdata} to `{properties}`") + + return client, userdata, mid, granted_qos, properties + + return on_subscribe + + @staticmethod + def _get_on_disconnect_callback() -> callable: + + def on_disconnect(client, userdata, rc): + # print(f"Disconnected from from `{properties}`") + + return client, userdata, rc + + return on_disconnect + + @staticmethod + def _get_on_unsubscribe_callback() -> callable: + + def on_unsubscribe(client, userdata, mid): + # print(f"Unsubscribed `{userdata}` from `{properties}`") + + return client, userdata, mid + + return on_unsubscribe diff --git a/agrirouter/messaging/decode.py b/agrirouter/messaging/decode.py new file mode 100644 index 00000000..839a0e48 --- /dev/null +++ b/agrirouter/messaging/decode.py @@ -0,0 +1,50 @@ +import base64 +from ctypes import Union + +from google.protobuf.any_pb2 import Any +from google.protobuf.internal.decoder import _DecodeVarint + +from agrirouter.generated.commons.message_pb2 import Messages +from agrirouter.generated.messaging.response.payload.account.endpoints_pb2 import ListEndpointsResponse +from agrirouter.generated.messaging.response.payload.feed.feed_response_pb2 import HeaderQueryResponse, \ + MessageQueryResponse +from agrirouter.generated.messaging.response.response_pb2 import ResponseEnvelope, ResponsePayloadWrapper +from agrirouter.messaging.messages import DecodedMessage +from agrirouter.utils.type_url import TypeUrl + + +def read_properties_buffers_from_input_stream(input_stream) -> tuple: + result = [] + pos = 0 + while pos < len(input_stream): + msg_len, pos = _DecodeVarint(input_stream, pos) + + msg_buf = input_stream[pos:pos + msg_len] + result.append(msg_buf) + + pos += msg_len + + return tuple(result) + + +def decode_response(message: bytes) -> DecodedMessage: + input_stream = base64.b64decode(message) + response_envelope_buffer, response_payload_buffer = read_properties_buffers_from_input_stream(input_stream) + + envelope = ResponseEnvelope().MergeFromString(response_envelope_buffer) + payload = ResponsePayloadWrapper().MergeFromString(response_payload_buffer) + + message = DecodedMessage(envelope, payload) + + return message + + +def decode_details(details: Any): + if details.type_url == TypeUrl.get_type_url(Messages.__name__): + return Messages().MergeFromString(details.value) + elif details.type_url == TypeUrl.get_type_url(ListEndpointsResponse.__name__): + return ListEndpointsResponse().MergeFromString(details.value) + elif details.type_url == TypeUrl.get_type_url(HeaderQueryResponse.__name__): + return HeaderQueryResponse().MergeFromString(details.value) + elif details.type_url == TypeUrl.get_type_url(MessageQueryResponse.__name__): + return MessageQueryResponse().MergeFromString(details.value) diff --git a/agrirouter/messaging/encode.py b/agrirouter/messaging/encode.py new file mode 100644 index 00000000..fe74c229 --- /dev/null +++ b/agrirouter/messaging/encode.py @@ -0,0 +1,46 @@ +import base64 + +from google.protobuf.any_pb2 import Any +from google.protobuf.internal.encoder import _VarintBytes + +from agrirouter.generated.messaging.request.request_pb2 import RequestEnvelope, RequestPayloadWrapper +from agrirouter.messaging.parameters.service import MessageHeaderParameters, MessagePayloadParameters +from agrirouter.utils.utc_time_util import now_as_utc_timestamp +from agrirouter.utils.uuid_util import new_uuid + + +def write_proto_parts_to_buffer(parts: list, buffer: bytes = b""): + for part in parts: + part_size = part.ByteSize() + buffer += _VarintBytes(part_size) + buffer += part.SerializeToString() + + return buffer + + +def encode_message(header_parameters: MessageHeaderParameters, payload_parameters: MessagePayloadParameters) -> bytes: + request_envelope = encode_header(header_parameters) + request_payload = encode_payload(payload_parameters) + + raw_data = write_proto_parts_to_buffer([request_envelope, request_payload]) + + return base64.b64encode(raw_data) + + +def encode_header(header_parameters: MessageHeaderParameters) -> RequestEnvelope: + request_envelope = RequestEnvelope() + request_envelope.application_id = header_parameters.get_application_message_id() \ + if header_parameters.get_application_message_id() else new_uuid() + request_envelope.application_message_seq_no = header_parameters.get_application_message_seq_no() + request_envelope.technical_message_type = header_parameters.get_technical_message_type() + request_envelope.mode = header_parameters.get_mode() + request_envelope.timestamp = now_as_utc_timestamp() + return request_envelope + + +def encode_payload(payload_parameters: MessagePayloadParameters) -> RequestPayloadWrapper: + any_proto_wrapper = Any() + any_proto_wrapper.type_url = payload_parameters.get_type_url() + any_proto_wrapper.value = payload_parameters.get_value() + request_payload = RequestPayloadWrapper(any_proto_wrapper) + return request_payload diff --git a/agrirouter/messaging/enums.py b/agrirouter/messaging/enums.py new file mode 100644 index 00000000..1247118f --- /dev/null +++ b/agrirouter/messaging/enums.py @@ -0,0 +1,15 @@ +from agrirouter.auth.enums import BaseEnum + + +class TechnicalMessageType(BaseEnum): + EMPTY = "" + CAPABILITIES = "dke:capabilities" + SUBSCRIPTION = "dke:subscription" + LIST_ENDPOINTS = "dke:list_endpoints" + LIST_ENDPOINTS_UNFILTERED = "dke:list_endpoints_unfiltered" + FEED_CONFIRM = "dke:feed_confirm" + FEED_DELETE = "dke:feed_delete" + FEED_HEADER_QUERY = "dke:feed_header_query" + FEED_MESSAGE_QUERY = "dke:feed_message_query" + CLOUD_ONBOARD_ENDPOINTS = "dke:cloud_onboard_endpoints" + CLOUD_OFFBOARD_ENDPOINTS = "dke:cloud_offboard_endpoints" diff --git a/agrirouter/messaging/exceptions.py b/agrirouter/messaging/exceptions.py new file mode 100644 index 00000000..3df29d4c --- /dev/null +++ b/agrirouter/messaging/exceptions.py @@ -0,0 +1,9 @@ +from agrirouter.onboarding.exceptions import AgriRouuterBaseException + + +class TypeUrlNotFoundError(AgriRouuterBaseException): + _message = "Given type url not found" + + +class WrongFieldError(AgriRouuterBaseException): + _message = "Unknown field" diff --git a/agrirouter/messaging/messages.py b/agrirouter/messaging/messages.py new file mode 100644 index 00000000..1e5228fd --- /dev/null +++ b/agrirouter/messaging/messages.py @@ -0,0 +1,115 @@ +import json +from datetime import datetime, timezone +from typing import Union, List, Dict + +from agrirouter.messaging.exceptions import WrongFieldError + + +class EncodedMessage: + + def __init__(self, id_, content): + self.id_ = id_ + self.content = content + + def get_id(self): + return self.id_ + + def get_content(self): + return self.content + + +class DecodedMessage: + def __init__(self, response_envelope, response_payload): + self.response_envelope = response_envelope + self.response_payload = response_payload + + def get_response_payload(self): + return self.response_payload + + def get_response_envelope(self): + return self.response_envelope + + +class Message: + MESSAGE = "message" + TIMESTAMP = "timestamp" + + def __init__(self, content): + self.content = content + self.timestamp = datetime.utcnow() + + def json_serialize(self) -> dict: + return { + self.MESSAGE: self.content, + self.TIMESTAMP: self.timestamp.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + } + + +class Command: + MESSAGE = "message" + + def __init__(self, message: str = None): + self.message = message + + def json_deserialize(self, data: Union[Dict[str, str], str]): + messages = data if type(data) == list else json.loads(data) + for key, value in messages.keys(): + if key == self.MESSAGE: + self.message = value + else: + raise WrongFieldError(f"Unknown field `{key}` for {self.__class__}") + + def get_message(self) -> str: + return self.message + + def set_message(self, message: str): + self.message = message + + +class OutboxMessage: + + CAPABILITY_ALTERNATE_ID = "capabilityAlternateId" + SENSOR_ALTERNATE_ID = "sensorAlternateId" + COMMAND = "command" + + def __init__(self, + capability_alternate_id: str = None, + sensor_alternate_id: str = None, + command: Command = None, + ): + self.capability_alternate_id = capability_alternate_id + self.sensor_alternate_id = sensor_alternate_id + self.command = command + + def json_deserialize(self, data: Union[list, str]): + data = data if type(data) == list else json.loads(data) + for key, value in data.keys(): + if key == self.CAPABILITY_ALTERNATE_ID: + self.capability_alternate_id = value + elif key == self.SENSOR_ALTERNATE_ID: + self.sensor_alternate_id = value + elif key == self.COMMAND: + self.command = Command.json_deserialize(value) + else: + raise WrongFieldError(f"Unknown field `{key}` for {self.__class__}") + + def get_capability_alternate_id(self) -> str: + return self.capability_alternate_id + + def set_capability_alternate_id(self, capability_alternate_id: str) -> None: + self.capability_alternate_id = capability_alternate_id + + def get_sensor_alternate_id(self) -> str: + return self.sensor_alternate_id + + def set_sensor_alternate_id(self, sensor_alternate_id: str) -> None: + self.sensor_alternate_id = sensor_alternate_id + + def get_command(self) -> Command: + return self.command + + def set_command(self, command: Command) -> None: + self.command = command + + def json_deserialize(self): + pass diff --git a/agrirouter/constants/keys.py b/agrirouter/messaging/parameters/__init__.py similarity index 100% rename from agrirouter/constants/keys.py rename to agrirouter/messaging/parameters/__init__.py diff --git a/agrirouter/messaging/parameters/dto.py b/agrirouter/messaging/parameters/dto.py new file mode 100644 index 00000000..3c1404de --- /dev/null +++ b/agrirouter/messaging/parameters/dto.py @@ -0,0 +1,91 @@ +from copy import deepcopy +from typing import List + +from agrirouter.messaging.messages import EncodedMessage +from agrirouter.onboarding.response import BaseOnboardingResonse + + +class Parameters: + def __init__(self, + *, + application_message_seq_no: str, + application_message_id: int = None, + team_set_context_id: str + ): + self.application_message_seq_no = application_message_seq_no + self.application_message_id = application_message_id + self.team_set_context_id = team_set_context_id + + def get_application_message_seq_no(self): + return self.application_message_seq_no + + def get_application_message_id(self): + return self.application_message_id + + def get_team_set_context_id(self): + return self.team_set_context_id + + def set_application_message_seq_no(self, application_message_seq_no): + self.application_message_seq_no = application_message_seq_no + + def set_application_message_id(self, application_message_id): + self.application_message_id = application_message_id + + def set_team_set_context_id(self, team_set_context_id): + self.team_set_context_id = team_set_context_id + + def validate(self): + pass + + +class MessageParameters(Parameters): + def __init__(self, + *, + application_message_seq_no: str, + application_message_id: int, + team_set_context_id: str, + onboarding_response: BaseOnboardingResonse + ): + super(MessageParameters, self).__init__( + application_message_seq_no=application_message_seq_no, + application_message_id=application_message_id, + team_set_context_id=team_set_context_id, + ) + + self.onboarding_response = onboarding_response + + def get_onboarding_response(self): + return self.onboarding_response + + +class MessagingParameters(MessageParameters): + + def __init__(self, + *, + application_message_seq_no: str = None, + application_message_id: int = None, + team_set_context_id: str = None, + onboarding_response: BaseOnboardingResonse, + encoded_messages=None + ): + + super(MessagingParameters, self).__init__( + application_message_seq_no=application_message_seq_no, + application_message_id=application_message_id, + team_set_context_id=team_set_context_id, + onboarding_response=onboarding_response, + ) + + self._encoded_messages = encoded_messages if encoded_messages else [] + + def get_encoded_messages(self): + return deepcopy(self._encoded_messages) + + def set_encoded_messages(self, encoded_messages: List[EncodedMessage]): + self._encoded_messages = encoded_messages + + def append_encoded_messages(self, encoded_message: EncodedMessage): + self._encoded_messages.append(encoded_message) + + def extend_encoded_messages(self, encoded_messages: List[EncodedMessage]): + self._encoded_messages.extend(encoded_messages) diff --git a/agrirouter/messaging/parameters/service.py b/agrirouter/messaging/parameters/service.py new file mode 100644 index 00000000..0769fa08 --- /dev/null +++ b/agrirouter/messaging/parameters/service.py @@ -0,0 +1,348 @@ +from abc import ABC, abstractmethod +from copy import deepcopy +from typing import List + +from agrirouter.generated.commons.chunk_pb2 import ChunkComponent +from agrirouter.generated.messaging.request.payload.endpoint.subscription_pb2 import Subscription +from agrirouter.generated.messaging.request.payload.feed.feed_requests_pb2 import ValidityPeriod +from agrirouter.messaging.parameters.dto import MessageParameters, Parameters + + +class MessageHeaderParameters(Parameters): + + def __init__(self, + *, + technical_message_type: str = None, + mode: str = None, + team_set_context_id: str = None, + application_message_seq_no: str = None, + recipients: list = None, + chunk_component: ChunkComponent = None, + application_message_id: int = None, + ): + super(MessageHeaderParameters, self).__init__( + application_message_seq_no=application_message_seq_no, + application_message_id=application_message_id, + team_set_context_id=team_set_context_id + ) + + self.technical_message_type = technical_message_type + self.mode = mode + self.recipients = recipients + self.chunk_component = chunk_component + + def get_technical_message_type(self) -> str: + return self.technical_message_type + + def get_mode(self) -> str: + return self.mode + + def get_recipients(self) -> list: + return self.recipients + + def get_chunk_component(self) -> ChunkComponent: + return self.chunk_component + + +class MessagePayloadParameters: + + def __init__(self, + *, + type_url: str, + value: str, + ): + + self.type_url = type_url + self.value = value + + def get_type_url(self) -> str: + return self.type_url + + def get_value(self) -> str: + return self.value + + +class CloudOnboardParameters(MessageParameters): + + def __init__(self, + # List[EndpointRegistrationDetails] - must be defined in generated by by proto schemes, + # but they are not + onboarding_requests: list = None, + **kwargs + ): + self.onboarding_requests = onboarding_requests if onboarding_requests else [] + super(CloudOnboardParameters, self).__init__(**kwargs) + + def get_onboarding_requests(self) -> list: + return self.onboarding_requests + + def set_onboarding_requests(self, onboarding_requests: list) -> None: + self.onboarding_requests = onboarding_requests + + def add_onboarding_requests(self, onboarding_request) -> None: + self.onboarding_requests.append(onboarding_request) + + def extend_onboarding_requests(self, onboarding_requests: list) -> None: + self.onboarding_requests.extend(onboarding_requests) + + +class CloudOffboardParameters(MessageParameters): + + def __init__(self, + endpoints: List[str] = None, + **kwargs + ): + self.endpoints = endpoints if endpoints else [] + super(CloudOffboardParameters, self).__init__(**kwargs) + + def get_endpoints(self) -> List[str]: + return self.endpoints + + def set_endpoints(self, endpoints: list) -> None: + self.endpoints = endpoints + + def add_endpoints(self, endpoint: str) -> None: + self.endpoints.append(endpoint) + + def extend_endpoints(self, endpoints: List[str]) -> None: + self.endpoints.extend(endpoints) + + +class CapabilityParameters(MessageParameters): + + def __init__(self, + application_id, + certification_version_id, + enable_push_notification, + capability_parameters: list = None, + **kwargs + ): + self.application_id = application_id + self.certification_version_id = certification_version_id + self.enable_push_notification = enable_push_notification + self.capability_parameters = capability_parameters if capability_parameters else [] + super(CapabilityParameters, self).__init__(**kwargs) + + def get_application_id(self): + return self.application_id + + def get_certification_version_id(self): + return self.certification_version_id + + def get_enable_push_notification(self): + return self.enable_push_notification + + def get_capability_parameters(self): + return deepcopy(self.capability_parameters) + + def set_application_id(self, application_id): + self.application_id = application_id + + def set_certification_version_id(self, certification_version_id): + self.certification_version_id = certification_version_id + + def set_enable_push_notification(self, enable_push_notification): + self.enable_push_notification = enable_push_notification + + def set_capability_parameters(self, capability_parameters: list): + self.capability_parameters = capability_parameters + + def add_capability_parameters(self, capability_parameter): + self.capability_parameters.append(capability_parameter) + + def extend_capability_parameters(self, capability_parameters: list): + self.capability_parameters.extend(capability_parameters) + + +class FeedConfirmParameters(MessageParameters): + def __init__(self, message_ids: list = None, **kwargs): + self.message_ids = message_ids if message_ids else [] + super(FeedConfirmParameters, self).__init__(**kwargs) + + def get_message_ids(self): + return deepcopy(self.message_ids) + + def set_message_ids(self, message_ids: list): + self.message_ids = message_ids + + def add_message_ids(self, message_id): + self.message_ids.append(message_id) + + def extend_message_ids(self, message_ids): + self.message_ids.extend(message_ids) + + +class FeedDeleteParameters(MessageParameters): + def __init__(self, + message_ids: list = None, + receivers: list = None, + validity_period: ValidityPeriod = None, + **kwargs): + self.message_ids = message_ids if message_ids else [] + self.receivers = receivers if receivers else [] + self.validity_period = validity_period + super(FeedDeleteParameters, self).__init__(**kwargs) + + def get_message_ids(self): + return deepcopy(self.message_ids) + + def set_message_ids(self, message_ids: list): + self.message_ids = message_ids + + def add_message_ids(self, message_id): + self.message_ids.append(message_id) + + def extend_message_ids(self, message_ids): + self.message_ids.extend(message_ids) + + def get_receivers(self): + return deepcopy(self.receivers) + + def set_receivers(self, receivers: list): + self.receivers = receivers + + def add_receivers(self, receiver): + self.receivers.append(receiver) + + def extend_receivers(self, receivers): + self.receivers.extend(receivers) + + def get_validity_period(self): + return self.validity_period + + def set_validity_period(self, validity_period: ValidityPeriod): + self.validity_period = validity_period + + +class ListEndpointsParameters(MessageParameters): + def __init__(self, + technical_message_type: str = None, + direction: str = None, + filtered: bool = False, + **kwargs): + self.technical_message_type = technical_message_type + self.direction = direction + self.filtered = filtered + super(ListEndpointsParameters, self).__init__(**kwargs) + + def get_technical_message_type(self) -> str: + return self.technical_message_type + + def set_technical_message_type(self, technical_message_type: str): + self.technical_message_type = technical_message_type + + def get_direction(self) -> str: + return self.direction + + def set_direction(self, direction: str): + self.direction = direction + + def is_filtered(self): + return self.filtered + + def set_filtered(self, filtered: bool): + self.filtered = filtered + + +class QueryMessageParameters(MessageParameters): + def __init__(self, + senders: list = None, + message_ids: list = None, + validity_period: ValidityPeriod = None, + **kwargs): + self.senders = senders + self.message_ids = message_ids + self.validity_period = validity_period + super(QueryMessageParameters, self).__init__(**kwargs) + + def get_senders(self) -> list: + return self.senders + + def set_senders(self, senders: list) -> None: + self.senders = senders + + def add_senders(self, sender) -> None: + self.senders.append(sender) + + def extend_senders(self, senders) -> None: + self.senders.extend(senders) + + def get_message_ids(self) -> list: + return self.message_ids + + def set_message_ids(self, message_ids: list) -> None: + self.message_ids = message_ids + + def add_message_ids(self, message_id) -> None: + self.message_ids.append(message_id) + + def extend_message_ids(self, message_ids) -> None: + self.message_ids.extend(message_ids) + + def get_validity_period(self) -> ValidityPeriod: + return self.validity_period + + def set_validity_period(self, validity_period: list) -> None: + self.validity_period = validity_period + + +class QueryHeaderParameters(MessageParameters): + def __init__(self, + senders: list = None, + message_ids: list = None, + validity_period: ValidityPeriod = None, + **kwargs): + self.senders = senders + self.message_ids = message_ids + self.validity_period = validity_period + super(QueryHeaderParameters, self).__init__(**kwargs) + + def get_senders(self) -> list: + return self.senders + + def set_senders(self, senders: list) -> None: + self.senders = senders + + def add_senders(self, sender) -> None: + self.senders.append(sender) + + def extend_senders(self, senders) -> None: + self.senders.extend(senders) + + def get_message_ids(self) -> list: + return self.message_ids + + def set_message_ids(self, message_ids: list) -> None: + self.message_ids = message_ids + + def add_message_ids(self, message_id) -> None: + self.message_ids.append(message_id) + + def extend_message_ids(self, message_ids) -> None: + self.message_ids.extend(message_ids) + + def get_validity_period(self) -> ValidityPeriod: + return self.validity_period + + def set_validity_period(self, validity_period: list) -> None: + self.validity_period = validity_period + + +class SubscriptionParameters(MessageParameters): + def __init__(self, + subscription_items: List[Subscription.MessageTypeSubscriptionItem] = None, + **kwargs): + self.subscription_items = subscription_items if subscription_items else [] + super(SubscriptionParameters, self).__init__(**kwargs) + + def get_subscription_items(self) -> List[Subscription.MessageTypeSubscriptionItem]: + return self.subscription_items + + def set_subscription_items(self, subscription_items: List[Subscription.MessageTypeSubscriptionItem]) -> None: + self.subscription_items = subscription_items + + def add_subscription_items(self, subscription_item: Subscription.MessageTypeSubscriptionItem) -> None: + self.subscription_items.append(subscription_item) + + def extend_direction(self, subscription_items: List[Subscription.MessageTypeSubscriptionItem]) -> None: + self.subscription_items.extend(subscription_items) diff --git a/agrirouter/messaging/request.py b/agrirouter/messaging/request.py new file mode 100644 index 00000000..4de0a69e --- /dev/null +++ b/agrirouter/messaging/request.py @@ -0,0 +1,25 @@ +from typing import List + +from agrirouter.messaging.messages import Message + + +class MessageRequest: + SENSOR_ALTERNATE_ID = "sensorAlternateId" + CAPABILITY_ALTERNATE_ID = "capabilityAlternateId" + MESSAGES = "measures" + + def __init__(self, + sensor_alternate_id: str, + capability_alternate_id: str, + messages: List[Message] + ): + self.sensor_alternate_id = sensor_alternate_id + self.capability_alternate_id = capability_alternate_id + self.messages = messages + + def json_serialize(self) -> dict: + return { + self.SENSOR_ALTERNATE_ID: self.sensor_alternate_id, + self.CAPABILITY_ALTERNATE_ID: self.capability_alternate_id, + self.MESSAGES: self.messages + } diff --git a/agrirouter/messaging/result.py b/agrirouter/messaging/result.py new file mode 100644 index 00000000..ba2df495 --- /dev/null +++ b/agrirouter/messaging/result.py @@ -0,0 +1,47 @@ +import json +from typing import List, Union + +from agrirouter.messaging.messages import OutboxMessage + + +class MessagingResult: + def __init__(self, messages_ids: List): + self.messages_ids = messages_ids + + def set_messages_ids(self, messages_ids): + self.messages_ids = messages_ids + + def get_messages_ids(self): + return self.messages_ids + + +class OutboxResponse: + def __init__(self, + status_code: int = None, + messages: List[OutboxMessage] = None + ): + + self.status_code = status_code + self.messages = messages if messages else [] + + def json_deserialize(self, data: Union[list, str]): + messages = data if type(data) == list else json.loads(data) + self.set_messages([OutboxMessage.json_deserialize(message) for message in messages]) + + def get_status_code(self) -> int: + return self.status_code + + def set_status_code(self, status_code: int) -> None: + self.status_code = status_code + + def get_messages(self) -> List[OutboxMessage]: + return self.messages + + def set_messages(self, messages: List[OutboxMessage]) -> None: + self.messages = messages + + def add_messages(self, message: OutboxMessage) -> None: + self.messages.append(message) + + def extend_messages(self, messages: List[OutboxMessage]) -> None: + self.messages.extend(messages) diff --git a/agrirouter/environments/enums.py b/agrirouter/messaging/services/__init__.py similarity index 100% rename from agrirouter/environments/enums.py rename to agrirouter/messaging/services/__init__.py diff --git a/agrirouter/messaging/services/cloud.py b/agrirouter/messaging/services/cloud.py new file mode 100644 index 00000000..cd40a465 --- /dev/null +++ b/agrirouter/messaging/services/cloud.py @@ -0,0 +1,71 @@ +from agrirouter.generated.cloud_provider_integration.cloud_virtualized_app_registration_pb2 import OnboardingRequest, \ + OffboardingRequest +from agrirouter.generated.messaging.request.request_pb2 import RequestEnvelope +from agrirouter.messaging.encode import encode_message +from agrirouter.messaging.enums import TechnicalMessageType +from agrirouter.messaging.messages import EncodedMessage +from agrirouter.messaging.parameters.service import MessageHeaderParameters, MessagePayloadParameters, \ + CloudOnboardParameters, CloudOffboardParameters +from agrirouter.messaging.services.messaging import AbstractService +from agrirouter.utils.type_url import TypeUrl +from agrirouter.utils.uuid_util import new_uuid + + +class CloudOnboardService(AbstractService): + + @staticmethod + def encode(parameters: CloudOnboardParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.CLOUD_ONBOARD_ENDPOINTS.value + ) + + onboarding_request = OnboardingRequest( + onboarding_requests=parameters.get_onboarding_requests() + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(OnboardingRequest.__name__), + value=onboarding_request.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class CloudOffboardService(AbstractService): + + @staticmethod + def encode(parameters: CloudOffboardParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.CLOUD_OFFBOARD_ENDPOINTS.value + ) + + offboarding_request = OffboardingRequest( + endpoints=parameters.get_endpoints() + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(OffboardingRequest.__name__), + value=offboarding_request.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message diff --git a/agrirouter/messaging/services/commons.py b/agrirouter/messaging/services/commons.py new file mode 100644 index 00000000..3e368632 --- /dev/null +++ b/agrirouter/messaging/services/commons.py @@ -0,0 +1,90 @@ +import os +from abc import ABC, abstractmethod + +import requests + +from agrirouter.messaging.certification import create_certificate_file +from agrirouter.messaging.clients.mqtt import MqttClient +from agrirouter.messaging.messages import Message +from agrirouter.messaging.request import MessageRequest +from agrirouter.messaging.result import MessagingResult + + +class AbstractMessagingClient(ABC): + + @staticmethod + def create_message_request(parameters) -> MessageRequest: + messages = [] + for encoded_message in parameters.get_encoded_messages(): + message = Message(encoded_message) + messages.append(message) + message_request = MessageRequest( + parameters.get_sensor_alternate_id(), + parameters.get_capability_alternate_id(), + messages + ) + return message_request + + @abstractmethod + def send(self, parameters): + ... + + +class HttpMessagingService(AbstractMessagingClient): + + def send(self, parameters) -> MessagingResult: + request = self.create_message_request(parameters) + cert_file_path = create_certificate_file(parameters.get_onboarding_response()) + try: + response = requests.post( + url=parameters.get_onboarding_response().get_connection_criteria().get_measures(), + headers={"Content-type": "application/json"}, + data=request.json_serialize(), + cert=( + cert_file_path, + parameters.get_onboarding_response().get_authentication().get_secret() + ), + ) + finally: + os.remove(cert_file_path) + result = MessagingResult([parameters.get_message_id()]) + return result + + def subscribe(self): + pass + + def unsubscribe(self): + pass + + +class MqttMessagingService(AbstractMessagingClient): + + def __init__(self, + onboarding_response, + on_message_callback: callable = None, + ): + + self.onboarding_response = onboarding_response + self.client = MqttClient( + client_id=self.onboarding_response.get_client_id(), + on_message_callback=on_message_callback, + ) + self.client.connect( + self.onboarding_response.get_connection_criteria().get_host(), + self.onboarding_response.get_connection_criteria().get_port() + ) + + def send(self, parameters, qos: int = 0) -> MessagingResult: + mqtt_payload = self.create_message_request(parameters) + self.client.publish( + self.onboarding_response.get_connection_criteria().get_measures(), mqtt_payload, + qos=qos + ) + result = MessagingResult([parameters.get_message_id()]) + return result + + def subscribe(self): + pass + + def unsubscribe(self): + pass diff --git a/agrirouter/messaging/services/http/__init__.py b/agrirouter/messaging/services/http/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/agrirouter/messaging/services/http/outbox.py b/agrirouter/messaging/services/http/outbox.py new file mode 100644 index 00000000..b81bfcbf --- /dev/null +++ b/agrirouter/messaging/services/http/outbox.py @@ -0,0 +1,30 @@ +import os + +import requests + +from agrirouter.messaging.result import OutboxResponse + +from agrirouter.messaging.certification import create_certificate_file + + +class OutboxService: + + def fetch(self, onboarding_response) -> OutboxResponse: + cert_file_path = create_certificate_file(onboarding_response) + try: + response = requests.get( + url=onboarding_response.get_connection_criteria().get_commands(), + headers={"Content-type": "application/json"}, + cert=( + cert_file_path, + onboarding_response.get_authentication().get_secret() + ), + ) + finally: + os.remove(cert_file_path) + + outbox_response = OutboxResponse(status_code=response.status_code) + outbox_response.json_deserialize(response.json()["contents"]) + + return outbox_response + diff --git a/agrirouter/messaging/services/messaging.py b/agrirouter/messaging/services/messaging.py new file mode 100644 index 00000000..e071b028 --- /dev/null +++ b/agrirouter/messaging/services/messaging.py @@ -0,0 +1,254 @@ +from agrirouter.generated.messaging.request.payload.account.endpoints_pb2 import ListEndpointsQuery +from agrirouter.generated.messaging.request.payload.endpoint.capabilities_pb2 import CapabilitySpecification +from agrirouter.generated.messaging.request.payload.endpoint.subscription_pb2 import Subscription +from agrirouter.generated.messaging.request.payload.feed.feed_requests_pb2 import MessageConfirm, MessageQuery +from agrirouter.generated.messaging.request.request_pb2 import RequestEnvelope +from agrirouter.messaging.encode import encode_message +from agrirouter.messaging.enums import TechnicalMessageType +from agrirouter.messaging.messages import EncodedMessage +from agrirouter.messaging.parameters.dto import MessageParameters, MessagingParameters +from agrirouter.messaging.parameters.service import MessageHeaderParameters, MessagePayloadParameters, \ + CapabilityParameters, FeedConfirmParameters, FeedDeleteParameters, ListEndpointsParameters, \ + SubscriptionParameters, QueryHeaderParameters, QueryMessageParameters +from agrirouter.utils.type_url import TypeUrl +from agrirouter.utils.uuid_util import new_uuid + + +class AbstractService: + + def __init__(self, messaging_service): + self.messaging_service = messaging_service + + def send(self, parameters): + messaging_parameters = MessagingParameters( + onboarding_response=parameters.get_onboarding_response(), + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + ) + encoded_messages = self.encode(parameters) + messaging_parameters.set_encoded_messages([encoded_messages.get_content()]) + return self.messaging_service.send(messaging_parameters) + + @staticmethod + def encode(*args, **kwargs) -> EncodedMessage: + ... + + +class CapabilityService(AbstractService): + + @staticmethod + def encode(parameters: CapabilityParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.CAPABILITIES.value + ) + + capability_specification = CapabilitySpecification( + app_certification_id=parameters.get_application_id(), + app_certification_version_id=parameters.get_certification_version_id(), + enable_push_notifications=parameters.get_enable_push_notification() + ) + if parameters.get_capability_parameters(): + capability_specification.capabilities = parameters.get_capability_parameters() + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(CapabilitySpecification.__name__), + value=capability_specification.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class FeedConfirmService(AbstractService): + + @staticmethod + def encode(parameters: FeedConfirmParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.FEED_CONFIRM.value + ) + + message_confirm = MessageConfirm( + message_ids=parameters.get_message_ids() + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(MessageConfirm.__name__), + value=message_confirm.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class FeedDeleteService(AbstractService): + + @staticmethod + def encode(parameters: FeedDeleteParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.FEED_CONFIRM.value + ) + + message_confirm = MessageConfirm( + message_ids=parameters.get_message_ids() + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(MessageConfirm.__name__), + value=message_confirm.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class ListEndpointsService(AbstractService): + + @staticmethod + def encode(parameters: ListEndpointsParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.LIST_ENDPOINTS.value if parameters.is_filtered() + else TechnicalMessageType.LIST_ENDPOINTS_UNFILTERED.value + ) + + list_endpoints_query = ListEndpointsQuery( + technical_message_type=parameters.get_technical_message_type(), + direction=parameters.get_direction() + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(ListEndpointsQuery.__name__), + value=list_endpoints_query.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class QueryMessagesService(AbstractService): + + @staticmethod + def encode(parameters: QueryMessageParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.FEED_MESSAGE_QUERY.value + ) + + message_query = MessageQuery( + senders=parameters.get_senders(), + message_ids=parameters.get_message_ids(), + validity_period=parameters.get_validity_period(), + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(MessageQuery.__name__), + value=message_query.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class QueryHeaderService(AbstractService): + + @staticmethod + def encode(parameters: QueryHeaderParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.FEED_HEADER_QUERY.value + ) + + message_query = MessageQuery( + senders=parameters.get_senders(), + message_ids=parameters.get_message_ids(), + validity_period=parameters.get_validity_period(), + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(MessageQuery.__name__), + value=message_query.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message + + +class SubscriptionService(AbstractService): + + @staticmethod + def encode(parameters: SubscriptionParameters) -> EncodedMessage: + message_header_parameters = MessageHeaderParameters( + application_message_id=parameters.get_application_message_id(), + application_message_seq_no=parameters.get_application_message_seq_no(), + team_set_context_id=parameters.get_team_set_context_id(), + mode=RequestEnvelope.Mode.Value("DIRECT"), + technical_message_type=TechnicalMessageType.SUBSCRIPTION.value + ) + + subscription = Subscription( + technical_message_types=parameters.get_subscription_items(), + ) + + message_payload_parameters = MessagePayloadParameters( + type_url=TypeUrl.get_type_url(Subscription.__name__), + value=subscription.SerializeToString() + ) + + message_content = encode_message(message_header_parameters, message_payload_parameters) + encoded_message = EncodedMessage( + id_=new_uuid(), + content=message_content + ) + + return encoded_message diff --git a/agrirouter/onboarding/headers.py b/agrirouter/onboarding/headers.py index 20fcf6fa..a1e0d61c 100644 --- a/agrirouter/onboarding/headers.py +++ b/agrirouter/onboarding/headers.py @@ -1,3 +1,4 @@ +import base64 from abc import ABC, abstractmethod from agrirouter.constants.media_types import ContentTypes @@ -34,16 +35,17 @@ def __init__(self, def get_header(self) -> dict: return self.params - def sign(self, signature): - self.params["X-Agrirouter-Signature"] = signature + def sign(self, signature: bytes): + print(signature) + self.params["X-Agrirouter-Signature"] = base64.b64encode(signature).decode() + print(self.params["X-Agrirouter-Signature"]) def _set_params(self, reg_code: str, application_id: str, signature: str, content_type: str): header = dict() header["Authorization"] = f"Bearer {reg_code}" header["Content-Type"] = content_type header["X-Agrirouter-ApplicationId"] = application_id - if signature: - header["X-Agrirouter-Signature"] = signature + header["X-Agrirouter-Signature"] = signature if signature else "" self.params = header diff --git a/agrirouter/onboarding/onboarding.py b/agrirouter/onboarding/onboarding.py index 0d0094e6..155d08dc 100644 --- a/agrirouter/onboarding/onboarding.py +++ b/agrirouter/onboarding/onboarding.py @@ -1,3 +1,5 @@ +import json + import requests from agrirouter.environments.environmental_services import EnvironmentalService @@ -6,7 +8,8 @@ from agrirouter.onboarding.parameters import SoftwareOnboardingParameter, BaseOnboardingParameter, CUOnboardingParameter from agrirouter.onboarding.request import SoftwareOnboardingRequest, BaseOnboardingRequest, CUOnboardingRequest from agrirouter.onboarding.request_body import SoftwareOnboardingBody, CUOnboardingBody -from agrirouter.onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, CUOnboardingResponse +from agrirouter.onboarding.response import SoftwareVerifyOnboardingResponse, SoftwareOnboardingResponse, \ + CUOnboardingResponse class SoftwareOnboarding(EnvironmentalService): @@ -31,7 +34,7 @@ def _perform_request(self, params: BaseOnboardingParameter, url: str) -> request if request.is_signed: return requests.post( url=request.get_url(), - data=request.get_data(), + data=json.dumps(request.get_data()), headers=request.get_header() ) raise RequestNotSigned diff --git a/agrirouter/onboarding/parameters.py b/agrirouter/onboarding/parameters.py index f88be38c..1ca75312 100644 --- a/agrirouter/onboarding/parameters.py +++ b/agrirouter/onboarding/parameters.py @@ -1,4 +1,5 @@ from abc import ABC, abstractmethod +from datetime import datetime from agrirouter.constants.media_types import ContentTypes from agrirouter.onboarding.enums import CertificateTypes @@ -20,15 +21,16 @@ def get_body_params(self, *args, **kwargs): class SoftwareOnboardingParameter(BaseOnboardingParameter): def __init__(self, + *, id_, application_id, certification_version_id, gateway_id, - utc_timestamp, time_zone, reg_code, + utc_timestamp=None, content_type=ContentTypes.APPLICATION_JSON.value, - certificate_type=CertificateTypes.P12.value, + certificate_type=CertificateTypes.PEM.value, ): self.id_ = id_ @@ -37,7 +39,8 @@ def __init__(self, self.certification_version_id = certification_version_id self.gateway_id = str(gateway_id) self.certificate_type = certificate_type - self.utc_timestamp = str(utc_timestamp) + self.utc_timestamp = str(utc_timestamp) if utc_timestamp \ + else datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ") self.time_zone = str(time_zone) self.reg_code = reg_code diff --git a/agrirouter/onboarding/request.py b/agrirouter/onboarding/request.py index aae1e653..1e7113b0 100644 --- a/agrirouter/onboarding/request.py +++ b/agrirouter/onboarding/request.py @@ -19,7 +19,7 @@ def get_header(self): return self.header.get_header() def sign(self, private_key): - signature = create_signature(self.body.json(new_lines=False), private_key) + signature = create_signature(self.body.json(), private_key) self.header.sign(signature) @property diff --git a/agrirouter/onboarding/request_body.py b/agrirouter/onboarding/request_body.py index d1c108eb..951ab01d 100644 --- a/agrirouter/onboarding/request_body.py +++ b/agrirouter/onboarding/request_body.py @@ -1,5 +1,6 @@ import json from abc import ABC, abstractmethod +from datetime import datetime from agrirouter.onboarding.enums import CertificateTypes, GateWays from agrirouter.onboarding.exceptions import WrongCertificationType, WrongGateWay @@ -25,18 +26,21 @@ def json(self, *args, **kwargs): class SoftwareOnboardingBody(BaseOnboardingBody): def __init__(self, + *, id_, application_id, certification_version_id, gateway_id, certificate_type, - utc_timestamp, - time_zone + time_zone, + utc_timestamp=None ): self._validate_certificate_type(certificate_type) self._validate_gateway_id(gateway_id) + utc_timestamp = utc_timestamp if utc_timestamp else datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ") + self._set_params( id_, application_id, @@ -70,11 +74,8 @@ def _set_params(self, "timeZone": time_zone, } - def json(self, new_lines: bool = True) -> str: - result = json.dumps(self.get_parameters(), indent="") - if not new_lines: - return result.replace("\n", "") - return result + def json(self) -> str: + return json.dumps(self.get_parameters()) @staticmethod def _validate_certificate_type(certificate_type: str) -> None: diff --git a/agrirouter/onboarding/response.py b/agrirouter/onboarding/response.py index 4718b641..cab6bca0 100644 --- a/agrirouter/onboarding/response.py +++ b/agrirouter/onboarding/response.py @@ -6,6 +6,18 @@ class BaseOnboardingResonse: def __init__(self, http_response: Response): self.response: Response = http_response + def get_connection_criteria(self) -> dict: + response_data = self.data() + return response_data.get("connectionCriteria") + + def get_sensor_alternate_id(self): + response_data = self.data() + return response_data.get("sensorAlternateId") + + def get_authentication(self): + response_data = self.data() + return response_data.get("authentication") + @property def data(self): return self.response.json() @@ -30,7 +42,18 @@ class SoftwareOnboardingResponse(BaseOnboardingResonse): """ Response from onboarding request used for Farming Software or Telemetry Platform """ - pass + + def get_connection_criteria(self) -> dict: + response_data = self.data() + return response_data.get("connectionCriteria") + + def get_sensor_alternate_id(self): + response_data = self.data() + return response_data.get("sensorAlternateId") + + def get_authentication(self): + response_data = self.data() + return response_data.get("authentication") class CUOnboardingResponse(BaseOnboardingResonse): diff --git a/agrirouter/utils/__init__.py b/agrirouter/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/agrirouter/utils/type_url.py b/agrirouter/utils/type_url.py new file mode 100644 index 00000000..71f4c6df --- /dev/null +++ b/agrirouter/utils/type_url.py @@ -0,0 +1,45 @@ +from agrirouter.generated.cloud_provider_integration.cloud_virtualized_app_registration_pb2 import OnboardingResponse, \ + OnboardingRequest +from agrirouter.generated.commons.message_pb2 import Messages +from agrirouter.generated.messaging.request.payload.account.endpoints_pb2 import ListEndpointsQuery +from agrirouter.generated.messaging.request.payload.endpoint.capabilities_pb2 import CapabilitySpecification +from agrirouter.generated.messaging.request.payload.endpoint.subscription_pb2 import Subscription +from agrirouter.generated.messaging.request.payload.feed.feed_requests_pb2 import MessageDelete, MessageConfirm, \ + MessageQuery +from agrirouter.generated.messaging.response.payload.account.endpoints_pb2 import ListEndpointsResponse +from agrirouter.generated.messaging.response.payload.feed.feed_response_pb2 import HeaderQueryResponse, \ + MessageQueryResponse +from agrirouter.messaging.exceptions import TypeUrlNotFoundError + + +class TypeUrl: + prefix = "types.agrirouter.com/" + + @classmethod + def get_type_url(cls, class_): + if class_.__name__ == Messages.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == ListEndpointsResponse.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == HeaderQueryResponse.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == MessageQueryResponse.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == MessageDelete.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == MessageConfirm.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == OnboardingResponse.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == OnboardingRequest.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == CapabilitySpecification.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == Subscription.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == MessageQuery.__name__: + return cls.prefix + class_.__name__ + elif class_.__name__ == ListEndpointsQuery.__name__: + return cls.prefix + class_.__name__ + else: + raise TypeUrlNotFoundError(f"The {class_} type url not found") diff --git a/agrirouter/utils/utc_time_util.py b/agrirouter/utils/utc_time_util.py new file mode 100644 index 00000000..b86f3afb --- /dev/null +++ b/agrirouter/utils/utc_time_util.py @@ -0,0 +1,6 @@ +from datetime import datetime + + +def now_as_utc_timestamp(): + timestamp = datetime.utcnow() + return timestamp.strftime("%Y-%m-%dT%H:%M:%S.%fZ") diff --git a/agrirouter/utils/uuid_util.py b/agrirouter/utils/uuid_util.py new file mode 100644 index 00000000..0c9bd872 --- /dev/null +++ b/agrirouter/utils/uuid_util.py @@ -0,0 +1,5 @@ +import uuid + + +def new_uuid(): + return uuid.uuid4() diff --git a/conftest.py b/conftest.py new file mode 100644 index 00000000..c36194f0 --- /dev/null +++ b/conftest.py @@ -0,0 +1,13 @@ +import pytest +from tests.constants import public_key, private_key, auth_result_url + + +@pytest.fixture(scope="session") +def authorization(): + from agrirouter.auth.auth import Authorization + + auth_client = Authorization("QA", public_key=public_key, private_key=private_key) + auth_response = auth_client.extract_auth_response(auth_result_url) + auth_client.verify_auth_response(auth_response) + auth_data = auth_response.get_auth_result() + return auth_data diff --git a/examples.txt b/examples.txt new file mode 100644 index 00000000..f0fa895a --- /dev/null +++ b/examples.txt @@ -0,0 +1,72 @@ +>>> private_key = ... # store here your private key you get in AR UI during application creation +>>> public_key = ... # store here your public key you get in AR UI during application creation +>>> application_id = "8c947a45-c57d-4fd2-affc-206e2sdg3a50" # # store here your application id. You can find it in AR UI + + +>>> ######################################################## +>>> # Authorization + +>>> import agrirouter as ar + +>>> auth_params = ar.AuthUrlParameter(application_id=application_id, response_type="onboard") +>>> auth_client = ar.Authorization("QA", public_key=public_key, private_key=private_key) +>>> auth_url = auth_client.get_auth_request_url(auth_params) # use this url to authorize the user as described at https://docs.my-agrirouter.com/agrirouter-interface-documentation/latest/integration/authorization.html#perform-authorization + +>>> auth_result_url = ... # the url the user was redirected after his authorization. +>>> auth_response = auth_client.extract_auth_response(auth_result_url) # auth_response containing the results of the auth process +>>> auth_client.verify_auth_response(auth_response) # you may verify auth_response to ensure answer was from AR + +>>> auth_response.is_successfull # True if user accepted application, False if he rejected +True +>>> auth_response.is_valid # Result of verification, if False, response was not validated by public key. Doesn't indicate was the auth successfull. Accessible only after response verifying +True + +>>> # Get dict containing data from auth process you will use for futher communication. +>>> # If auth was rejected, contains {"error"} key. +>>> # If auth was accepted, contains {signature, state, token, credentials{account, expires, regcode}} keys +>>> # Even if response verifying was not processed or failed, the results will be returned. But in that case you act on your risk. +>>> auth_data = auth_response.get_auth_result() + +{'credentials': {'account': '0ba223gh-cg3b-4te5-boc9-77ghcfn136a0', + 'expires': '2021-09-23T16:08:43.888Z', + 'regcode': '8eloz190fd'}, + 'signature': 'SULf4QMWAfG4/EyT0rejkRfApnkJIOs4sxI5wxeB8TkIiv0MR6YFKw1tPIkM4lluZKHEIgr5WvM3b3op4I9TtEbzZf995R8GIlNP6yyP51TF/4vZMbka0q+2g1o0qw/yuDQcGz1RpOJWCuBOjMXu9quzGO8xvDW7LjrN+MA9rzJZYb1toNf51O0sdg21oLvrKrqvaErKcIoRJtTVJ51awOWMARDkGZahcRdWrZbdGUbQwIyKJQu4vH8+4ytlyXPSWEYwKE2VFoAjhzWsKODdRRxDbNNLWsW8sxKamdsPmOC8inHUFsFNoxLbwZEnKROm2s3OfKGYuibXOpXw==', + 'state': '46c81f94-d117-4658-9a38-a85692448219', + 'token': 'eyJhY2sdoT4IjoiMGJhMjRlZWUtYzMwYi00N2U1LWJkYzktNzcwM2NmYjEzNmEwIiwicmVnY29kZSI6IjhlYWNiMTk4ZmMiLCJleHBpcmVzIopGjjAyMS0wOS0y1O5xNjowODo0My44ODhaIn0='} + + + +>>> ######################################################## + +>>> # Onboarding + + +>>> from agrirouter.onboarding.enums import GateWays + +>>> id_ = "mydeviceid" +>>> certification_version_id = ... # get from AR UI +>>> utc_timestamp = "2018-06-20T07:29:23.457Z" +>>> time_zone = "+03:00" + +>>> onboarding_client = ar.SoftwareOnboarding("QA", public_key=public_key, private_key=private_key) +>>> onboarding_parameters = ar.SoftwareOnboardingParameter(id_=id_, application_id=application_id, certification_version_id=certification_version_id, gateway_id=GateWays.REST.value, utc_timestamp=utc_timestamp, time_zone=time_zone, reg_code=auth_data["credentials"]["regcode"]) +>>> onboarding_verifying_response = onboarding_client.verify(onboarding_parameters) +>>> onboarding_response = onboarding_client.onboard(onboarding_parameters) +>>> onboarding_response.status_code() +>>> onboarding_response.data() # or onboarding_response.text() + +{ + "authentication": { + "certificate": "-----BEGIN ENCRYPTED PRIVATE KEY-----\n...\n-----END ENCRYPTED PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n", + "secret": "77R8cjOGi9yTCBt2", + "type": "PEM" + }, + "capabilityAlternateId": "7bc8ab05-a0de-40db-a259-7deefb1265e9", + "connectionCriteria": { + "gatewayId": "3", + "measures": "https://dke-qa.eu10.cp.iot.sap/iot/gateway/rest/measures/c067272a-d3a7-4dcf-ab58-5c45ba66ad60", + "commands": "https://dke-qa.eu10.cp.iot.sap/iot/gateway/rest/commands/c067272a-d3a7-4dcf-ab58-5c45ba66ad60" + }, + "deviceAlternateId": "c067272a-d3a7-4dcf-ab58-5c45ba66ad60", + "sensorAlternateId": "5564ce96-385f-448a-9502-9ea3c940a259" +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e2da2ee2..9cd51d4f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,12 @@ cffi==1.14.6 charset-normalizer==2.0.6 cryptography==3.4.8 idna==3.2 +paho-mqtt==1.5.1 +protobuf==3.18.0 pycparser==2.20 requests==2.26.0 urllib3==1.26.7 +pytest==6.2.5 +black==21.9b0 +flake8==3.9.2 +pyflakes==2.3.1 diff --git a/tests/auth_test/test_response.py b/tests/auth_test/test_response.py new file mode 100644 index 00000000..75d0f679 --- /dev/null +++ b/tests/auth_test/test_response.py @@ -0,0 +1,22 @@ +"""Tests agrirouter/auth/response.py""" + +import re +from agrirouter.auth.response import AuthResponse + + +def test_decode_token(): + token = ( + "eyJhY2NvdW50IjoiMGJhMjRlZWUtYzMwYi00N2U1LWJkYzktNzcwM" + "2NmYjEzNmEwIiwicmVnY29kZSI6IjhlYWNiMTk4ZmMiLCJleHBpcm" + "VzIjoiMjAyMS0wOS0yM1QxNjowODo0My44ODhaIn0=" + ) + decoded_token = AuthResponse.decode_token(token) + assert isinstance(decoded_token["account"], str) + assert isinstance(decoded_token["expires"], str) + assert re.search(r"[\w]", decoded_token["regcode"]) + assert re.search(r"[\w]", decoded_token["account"]) + + +def test_get_auth_result(authorization): + assert isinstance(AuthResponse(authorization).get_auth_result(), dict) + assert AuthResponse(authorization).get_auth_result()["credentials"] diff --git a/tests/constants.py b/tests/constants.py new file mode 100644 index 00000000..c07044eb --- /dev/null +++ b/tests/constants.py @@ -0,0 +1,60 @@ +application_id = "8c947a45-c57d-42d2-affc-206e21d63a50" +ENV = "QA" +auth_result_url = ( + "http://fuf.me/?state=46c81f94-d117-4658-9a38-a85692448219&token=eyJhY2NvdW50IjoiMGJhMjRlZWUtYzMwY" + "i00N2U1LWJkYzktNzcwM2NmYjEzNmEwIiwicmVnY29kZSI6IjhlYWNiMTk4ZmMiLCJleHBpcmVzIjoiMjAyMS0wOS0yM1QxNj" + "owODo0My44ODhaIn0%3D&signature=SUL9SQMWAfG4%2FEyT0rejkRfAyioxJIOs4sxI5wxeB8TkIiv0MR6YFKw1tPIkM4ll" + "uZKHEIgr5WvM3b3SvII9TtEbzZf995R8GIlNP6yyP51TF%2F4vZMbkMjq%2B2g1o0qw%2FyuDQcGz1RpOJWCuBOjMXu9quzGO" + "8xvDW7LjrN%2BMA9rzJZYb1toNf51O0eO4BDWL5L1oLvrKrqvaErKcIoRJtTVJ51awOWMARDkGZahcRdWrZbdGUbQwIyKJQu4" + "vH8%2B4ytlyXPSWEYwKE2VFoAjhzWsKODdRRxDbNNLWsW8sxKamdXjSOC8inHUFsFNoxLbwZEnKROm2s3OfKGYuibXOpXw%3D%3D" +) +private_key = ( + "-----BEGIN PRIVATE KEY-----\n" + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8WVUWBhEiQYvo\n" + "DL9q/Z5LbIhqDtcdFYWBUV7A96AXJaNRA9J7m3a6es05S7pRynv9yT8i+bhz/qDf\n" + "18MPOaqLglTw58ylVtTGmIlIZr85KJecO5aQnKN1pz8LyKnQSk4IWMBZ0T6mcaEO\n" + "fLVcDCmLi3T9a07xT4g5i2PGnLI6nd1pf3sLuKEzUjp455xU3oJrP0HfwSc+DXZQ\n" + "YDk2Rk6mfPgEczBhRmqDFp44+WHgyq4CcXl92M5XdOSYVaRs/W6fcEmRTqjBxp1u\n" + "M3kNAIaOC4XNfxVV8kSCfZW0gVtuGqxGK+80OZay3Vc1nQZGm+IUVBHKbPVauhXS\n" + "UH0/28qbAgMBAAECggEANVX8vMBaEL/L/RnDCOqp7UTeOl5adx91j2G5+d4FhRiA\n" + "73usGpmzHOqSe/OgXvH+e6cGDIL3w00rREgGsiSL0XbGU/PoJTf6CAUA9zI1W1vN\n" + "1w2evPPGbBZAybb4s4WfJEjxq12QJrUNvRr+hoLhLuV+axb8o2P4uQbqab9Mz0ER\n" + "lczCbHi4VDs1fwmNR3o47T1J4Qffzv1nMlor3pSrDzRDebic7/DC5JFkYZNGUtHk\n" + "jKDF5Uv7Vzxgb4Of+i3JA5mRMqvG33pdenvvetwl9X69WOiC29bVlymSHyybBE4A\n" + "ItfCAHIiY3nUL7UqzoIXpsyPs3ftkiy3Hn7isVSpLQKBgQDjadkGlqIgXCKZ8RS6\n" + "a4iLTTTlh8Ur+vMrejBLPul1oxz2dRWZy8zykfNN2MPz7q2xT8wXGuxgj+jei/fi\n" + "Gk08+UudMhV5Dtshb3fFq0NFCBe1ZUEX/wAcKC4Ed9xuuHpe7HOKAG0AsnzS8MPC\n" + "lcMiL1/vz0GuRbsiyMY6hXweZQKBgQDUBmQNqOBWDTQkO/8MFHopo6Ju9iNvZ4fC\n" + "u4SWqL+5BO3nnQHAQyslsj8FNilqhgMI+zaFFbZMZPv5opBSaAR0CQanKxMe3c9I\n" + "XYkAJH2+M0fpp80LtxwShD411UDhIypzumfKe8vUXRW/8TWfl6VidfEVjxw6Rc2D\n" + "g9btI4k0/wKBgQC42plnGZq/4yTdLXJD9pUPZrrQuQQ1M8/mT3RiNclfri8kxxe/\n" + "5EG8C5dSeBkQd7sInmyve1sZQuFvxSbBy89s+NfV95gsxz6odwtMymHsAyACe0Pm\n" + "VYmpWZ/OUgAEoEAYWOuyCZaRMoT0knEOAt6TMx8wt7AUEOqE497+QvMZYQKBgQC6\n" + "ARlJenvEQjUaDKBFYrmBShK4MasIktThG0zINyZrFE35wR3GI6b4nRT4Z3mSABst\n" + "h+Vef5u8DWOYrurZwHMXsMtrYDiX/ZNZMuV7gIfnkmlmLFWQD4XLIMTKyVjvqcAW\n" + "YtOnKU+58CeiieO3LHxkkn97oF7tKEuRMtock+5M1QKBgC2fquqxXMrBEIoMGCZs\n" + "ooU5V9gOjFVKC52VWnTNgmOWTqgZuqxPJtCTN5wPvhOSggQuHPwBHa9ioshJ0dGE\n" + "6jdxGaJjAc82q2KZu9VEqoH/Xa2aS8dPEHwfJtzUVTia6WkrFtMFNaDMFd6byWDQ\n" + "ai+T4i2J3/SDL0BfsFWdQuje\n" + "-----END PRIVATE KEY-----" +) + +public_key = ( + "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvFlVFgYRIkGL6Ay/av2e\n" + "S2yIag7XHRWFgVFewPegFyWjUQPSe5t2unrNOUu6Ucp7/ck/Ivm4c/6g39fDDzmq\n" + "i4JU8OfMpVbUxpiJSGa/OSiXnDuWkJyjdac/C8ip0EpOCFjAWdE+pnGhDny1XAwp\n" + "i4t0/WtO8U+IOYtjxpyyOp3daX97C7ihM1I6eOecVN6Caz9B38EnPg12UGA5NkZO\n" + "pnz4BHMwYUZqgxaeOPlh4MquAnF5fdjOV3TkmFWkbP1un3BJkU6owcadbjN5DQCG\n" + "jguFzX8VVfJEgn2VtIFbbhqsRivvNDmWst1XNZ0GRpviFFQRymz1WroV0lB9P9vK\n" + "mwIDAQAB\n" + "-----END PUBLIC KEY-----" +) + +AR_PUBLIC_KEY = ( + "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8xF9661acn+iS+QS+9Y\n3HvTfUV" + "cismzbuvxHgHA7YeoOUFxyj3lkaTnXm7hzQe4wDEDgwpJSGAzxIIYSUXe\n8EsWLorg5O0tRexx5SP3+kj1i83DATBJCXP7k+bAF4" + "u2FVJphC1m2BfLxelGLjzx\nVAS/v6+EwvYaT1AI9FFqW/a2o92IsVPOh9oM9eds3lBOAbH/8XrmVIeHofw+XbTH\n1/7MLD6IE2+" + "HbEeY0F96nioXArdQWXcjUQsTch+p0p9eqh23Ak4ef5oGcZhNd4yp\nY8M6ppvIMiXkgWSPJevCJjhxRJRmndY+ajYGx7CLePx7wN" + "vxXWtkng3yh+7WiZ/Y\nqwIDAQAB\n-----END PUBLIC KEY-----" +) diff --git a/tests/enviroments_test/test_environmental_services.py b/tests/enviroments_test/test_environmental_services.py new file mode 100644 index 00000000..611e3172 --- /dev/null +++ b/tests/enviroments_test/test_environmental_services.py @@ -0,0 +1,11 @@ +"""Test agrirouter/environments/environmental_services.py""" + +import pytest +from agrirouter.environments.exceptions import InvalidEnvironmentSetup +from agrirouter.environments.environmental_services import EnvironmentalService +from tests.constants import ENV + + +def test_arclient_set_env(): + with pytest.raises(InvalidEnvironmentSetup): + assert EnvironmentalService("WRONG")._set_env("WRONG") diff --git a/tests/enviroments_test/test_environments.py b/tests/enviroments_test/test_environments.py new file mode 100644 index 00000000..8619bdc4 --- /dev/null +++ b/tests/enviroments_test/test_environments.py @@ -0,0 +1,213 @@ +"""Test agrirouter/environments/environments.py""" + +import pytest +from agrirouter.environments.environments import ProductionEnvironment, QAEnvironment +from tests.constants import application_id, auth_result_url + + +class TestProductionEnvironment: + def test_get_base_url(self): + assert ( + ProductionEnvironment().get_base_url() + == ProductionEnvironment._ENV_BASE_URL + ) + + def test_get_api_prefix(self): + assert ( + ProductionEnvironment().get_api_prefix() + == ProductionEnvironment._API_PREFIX + ) + + def test_get_registration_service_url(self): + assert ( + ProductionEnvironment().get_registration_service_url() + == ProductionEnvironment._REGISTRATION_SERVICE_URL + ) + + def test_get_onboard_url(self): + assert ( + ProductionEnvironment().get_onboard_url() + == ProductionEnvironment._REGISTRATION_SERVICE_URL + + ProductionEnvironment._API_PREFIX + + "/registration/onboard" + ) + + def test_get_secured_onboard_url(self): + assert ( + ProductionEnvironment().get_secured_onboard_url() + == ProductionEnvironment._REGISTRATION_SERVICE_URL + + ProductionEnvironment._API_PREFIX + + "/registration/onboard/request" + ) + + def test_get_verify_onboard_request_url(self): + assert ( + ProductionEnvironment().get_verify_onboard_request_url() + == ProductionEnvironment._REGISTRATION_SERVICE_URL + + ProductionEnvironment._API_PREFIX + + "/registration/onboard/verify" + ) + + def test_get_revoke_url(self): + assert ( + ProductionEnvironment().get_revoke_url() + == ProductionEnvironment._REGISTRATION_SERVICE_URL + + ProductionEnvironment._API_PREFIX + + "/registration/onboard/revoke" + ) + + def test_get_agrirouter_login_url(self): + assert ( + ProductionEnvironment().get_agrirouter_login_url() + == ProductionEnvironment._ENV_BASE_URL + + ProductionEnvironment._AGRIROUTER_LOGIN_URL + ) + + def test_get_secured_onboarding_authorization_url(self): + assert ProductionEnvironment().get_secured_onboarding_authorization_url( + application_id, str, "state", auth_result_url + ) == ProductionEnvironment._ENV_BASE_URL + ProductionEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="state", + redirect_uri=auth_result_url, + ) + with pytest.raises(AssertionError): + assert ProductionEnvironment().get_secured_onboarding_authorization_url( + application_id, str, "state", auth_result_url + ) == ProductionEnvironment._ENV_BASE_URL + ProductionEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="123", + redirect_uri=auth_result_url, + ) + with pytest.raises(AssertionError): + assert ProductionEnvironment().get_secured_onboarding_authorization_url( + application_id, dict, "state", auth_result_url + ) == ProductionEnvironment._ENV_BASE_URL + ProductionEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="state", + redirect_uri=auth_result_url, + ) + + def test_get_mqtt_server_url(self): + assert ProductionEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == ProductionEnvironment._MQTT_URL_TEMPLATE.format( + host="localhost", port="5000" + ) + with pytest.raises(AssertionError): + assert ProductionEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == ProductionEnvironment._MQTT_URL_TEMPLATE.format( + host="127.0.0.1", port="5000" + ) + with pytest.raises(AssertionError): + assert ProductionEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == ProductionEnvironment._MQTT_URL_TEMPLATE.format( + host="localhost", port="80" + ) + + def test_get_env_public_key(self): + assert ( + ProductionEnvironment().get_env_public_key() + == ProductionEnvironment.AR_PUBLIC_KEY + ) + + +class TestQAEnvironment: + def test_get_base_url(self): + assert QAEnvironment().get_base_url() == QAEnvironment._ENV_BASE_URL + + def test_get_api_prefix(self): + assert QAEnvironment().get_api_prefix() == QAEnvironment._API_PREFIX + + def test_get_registration_service_url(self): + assert ( + QAEnvironment().get_registration_service_url() + == QAEnvironment._REGISTRATION_SERVICE_URL + ) + + def test_get_onboard_url(self): + assert ( + QAEnvironment().get_onboard_url() + == QAEnvironment._REGISTRATION_SERVICE_URL + + QAEnvironment._API_PREFIX + + "/registration/onboard" + ) + + def test_get_secured_onboard_url(self): + assert ( + QAEnvironment().get_secured_onboard_url() + == QAEnvironment._REGISTRATION_SERVICE_URL + + QAEnvironment._API_PREFIX + + "/registration/onboard/request" + ) + + def test_get_verify_onboard_request_url(self): + assert ( + QAEnvironment().get_verify_onboard_request_url() + == QAEnvironment._REGISTRATION_SERVICE_URL + + QAEnvironment._API_PREFIX + + "/registration/onboard/verify" + ) + + def test_get_revoke_url(self): + assert ( + QAEnvironment().get_revoke_url() + == QAEnvironment._REGISTRATION_SERVICE_URL + + QAEnvironment._API_PREFIX + + "/registration/onboard/revoke" + ) + + def test_get_agrirouter_login_url(self): + assert ( + QAEnvironment().get_agrirouter_login_url() + == QAEnvironment._ENV_BASE_URL + QAEnvironment._AGRIROUTER_LOGIN_URL + ) + + def test_get_secured_onboarding_authorization_url(self): + assert QAEnvironment().get_secured_onboarding_authorization_url( + application_id, str, "state", auth_result_url + ) == QAEnvironment._ENV_BASE_URL + QAEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="state", + redirect_uri=auth_result_url, + ) + with pytest.raises(AssertionError): + assert QAEnvironment().get_secured_onboarding_authorization_url( + application_id, str, "state", auth_result_url + ) == QAEnvironment._ENV_BASE_URL + QAEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="123", + redirect_uri=auth_result_url, + ) + with pytest.raises(AssertionError): + assert QAEnvironment().get_secured_onboarding_authorization_url( + application_id, dict, "state", auth_result_url + ) == QAEnvironment._ENV_BASE_URL + QAEnvironment._SECURED_ONBOARDING_AUTHORIZATION_LINK_TEMPLATE.format( + application_id=application_id, + response_type=str, + state="state", + redirect_uri=auth_result_url, + ) + + def test_get_mqtt_server_url(self): + assert QAEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == QAEnvironment._MQTT_URL_TEMPLATE.format(host="localhost", port="5000") + with pytest.raises(AssertionError): + assert QAEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == QAEnvironment._MQTT_URL_TEMPLATE.format(host="127.0.0.1", port="5000") + with pytest.raises(AssertionError): + assert QAEnvironment().get_mqtt_server_url( + "localhost", "5000" + ) == QAEnvironment._MQTT_URL_TEMPLATE.format(host="localhost", port="80") + + def test_get_env_public_key(self): + assert QAEnvironment().get_env_public_key() == QAEnvironment.AR_PUBLIC_KEY diff --git a/tests/messaging_test/test_request.py b/tests/messaging_test/test_request.py new file mode 100644 index 00000000..5b978ec6 --- /dev/null +++ b/tests/messaging_test/test_request.py @@ -0,0 +1,15 @@ +"""Test agrirouter/messaging/request.py""" + +from agrirouter.messaging.messages import Message +from agrirouter.messaging.request import MessageRequest + + +def test_json_serialize(): + message_request = MessageRequest( + sensor_alternate_id="1", + capability_alternate_id="1", + messages=[Message(content="content")], + ).json_serialize() + assert isinstance(message_request, dict) + assert message_request["capabilityAlternateId"] == "1" + assert message_request["sensorAlternateId"] == "1" diff --git a/tests/onboarding_test/test_headers.py b/tests/onboarding_test/test_headers.py new file mode 100644 index 00000000..4a412082 --- /dev/null +++ b/tests/onboarding_test/test_headers.py @@ -0,0 +1,23 @@ +"""Test agrirouter/onboarding/headers.py""" +from agrirouter.constants.media_types import ContentTypes +from agrirouter.onboarding.headers import SoftwareOnboardingHeader + + +class TestSoftwareOnboardingHeader: + reg_code = "1AC2cs21W" + test_object = SoftwareOnboardingHeader(reg_code=reg_code, application_id=1) + test_object_1 = SoftwareOnboardingHeader( + reg_code=reg_code, application_id=1, content_type="json" + ) + + def test_get_header(self): + assert isinstance(self.test_object.get_header(), dict) + assert ( + self.test_object.get_header()["Authorization"] == "Bearer " + self.reg_code + ) + assert ( + self.test_object.get_header()["Content-Type"] + == ContentTypes.APPLICATION_JSON.value + ) + + assert self.test_object_1.get_header()["Content-Type"] == "json" diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..2aae4364 --- /dev/null +++ b/tox.ini @@ -0,0 +1,16 @@ +[flake8] +ignore = D203 +exclude = + .git, + __pycache__, + .pytest_cache + agrirouter_sdk_python.egg-info, + assets, + old, + build, + dist, + venv, + conftest.py, + *_pb2.py +max-line-length = 120 +max-complexity = 10