{"id":26256599,"url":"https://github.com/netcracker/qubership-maas-client","last_synced_at":"2026-05-19T08:38:38.188Z","repository":{"id":281179995,"uuid":"908910275","full_name":"Netcracker/qubership-maas-client","owner":"Netcracker","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-16T07:41:44.000Z","size":446,"stargazers_count":0,"open_issues_count":8,"forks_count":1,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-05-16T09:45:57.060Z","etag":null,"topics":["core","java","lib","maas","qubership-core"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Netcracker.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-27T09:14:45.000Z","updated_at":"2026-03-16T13:09:02.000Z","dependencies_parsed_at":"2026-02-16T12:02:56.021Z","dependency_job_id":null,"html_url":"https://github.com/Netcracker/qubership-maas-client","commit_stats":null,"previous_names":["netcracker/qubership-maas-client"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/Netcracker/qubership-maas-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcracker%2Fqubership-maas-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcracker%2Fqubership-maas-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcracker%2Fqubership-maas-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcracker%2Fqubership-maas-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Netcracker","download_url":"https://codeload.github.com/Netcracker/qubership-maas-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Netcracker%2Fqubership-maas-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33208150,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-19T07:54:09.561Z","status":"ssl_error","status_checked_at":"2026-05-19T07:54:08.508Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["core","java","lib","maas","qubership-core"],"created_at":"2025-03-13T20:18:38.781Z","updated_at":"2026-05-19T08:38:38.183Z","avatar_url":"https://github.com/Netcracker.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Maven build](https://github.com/Netcracker/qubership-maas-client/actions/workflows/maven-deploy.yml/badge.svg)](https://github.com/Netcracker/qubership-maas-client/actions/workflows/maven-deploy.yml)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?metric=coverage\u0026project=Netcracker_qubership-maas-client)](https://sonarcloud.io/summary/overall?id=Netcracker_qubership-maas-client)\n[![duplicated_lines_density](https://sonarcloud.io/api/project_badges/measure?metric=duplicated_lines_density\u0026project=Netcracker_qubership-maas-client)](https://sonarcloud.io/summary/overall?id=Netcracker_qubership-maas-client)\n[![vulnerabilities](https://sonarcloud.io/api/project_badges/measure?metric=vulnerabilities\u0026project=Netcracker_qubership-maas-client)](https://sonarcloud.io/summary/overall?id=Netcracker_qubership-maas-client)\n[![bugs](https://sonarcloud.io/api/project_badges/measure?metric=bugs\u0026project=Netcracker_qubership-maas-client)](https://sonarcloud.io/summary/overall?id=Netcracker_qubership-maas-client)\n[![code_smells](https://sonarcloud.io/api/project_badges/measure?metric=code_smells\u0026project=Netcracker_qubership-maas-client)](https://sonarcloud.io/summary/overall?id=Netcracker_qubership-maas-client)\n\n# MaaS Client\n\n\u003c!-- TOC --\u003e\n* [MaaS Client](#maas-client)\n* [Tiny, pure java client](#tiny-pure-java-client)\n  * [Prerequisite](#prerequisite)\n  * [Start](#start)\n  * [Kafka client usage example](#kafka-client-usage-example)\n    * [Context propagation](#context-propagation)\n  * [RabbitMQ client usage example](#rabbitmq-client-usage-example)\n    * [Context propagation](#context-propagation-)\n  * [Migration](#migration)\n\u003c!-- TOC --\u003e\n\nMaas client consist of two parts:\n* maas-client-core - Tiny, pure java client to MaaS\n* rabbit-context-propagation - utility classes for propagation and restoration of B/G version context\n* maas-client-quarkus - Core client with beans for Quarkus now located at: https://github.com/Netcracker/qubership-core-quarkus-extensions\n\n# Tiny, pure java client\nThin layer to MaaS with following requirements in mind:\n* as simple as it possible\n* minimal external dependencies\n* stay framework, cloud and platforms agnostic\n\nImportant notice to developer: import classes from `api` packages and avoid explicit importing of `impl` packages in your code as much as you can.\nDeveloping MaaS client is rules of thumb in mind were:\n* `api` packages will be backward compatible across minor releases and patches \n* `impl` packages may contain changes that can breaks backward compatibility\n\nAll changes in API across library releases will be conformed to semantic versioning rules (See https://semver.org/)  \n\n## Prerequisite\nPlease ensure, that your pod runtime environment variables contains:\n* `NAMESPACE` - namespace name in which microservice is deployed  \n* `CLOUD_SERVICE_NAME` - name of microservice \n\nTo add missed variables to your pod runtime environment, you need to edit your deployment chart files.  \n\n## Start\nFirst of all we need to create instance of [MaaSAPIClient](https://github.com/Netcracker/qubership-maas-client/blob/main/client/src/main/java/com/netcracker/cloud/maas/client/api/MaaSAPIClient.java). \nDefault implementation for this interface is [MaaSAPIClientImpl](https://github.com/Netcracker/qubership-maas-client/blob/main/client/src/main/java/com/netcracker/cloud/maas/client/impl/MaaSAPIClientImpl.java).\nMaaSAPIClientImpl requires single parameter to instantiate - M2M auth token supplier. This token will be used to:\n* interact with maas-agent microservice\n* subscribe to tenant-manager tenant activation/deactivation events (tenant-topics feature)\n* subscribe to control-plane service to watch on B/G version deploy/promote/rollback events\n\nIt's simple constructor call with token from cloud core libraries m2m-manager:\n```java\nMaaSClient client = new MaaSAPIClientImpl(() -\u003e M2MManager.getInstance().getToken().getToken());\n```\n   \n\n## Kafka client usage example\nAll MaaS operations for Kafka is collected in [KafkaMaaSClient](https://github.com/Netcracker/qubership-maas-client/blob/main/client/src/main/java/com/netcracker/cloud/maas/client/api/kafka/KafkaMaaSClient.java). To obtain *new* instance of MaaS Kafka client just call: \n```java\nKafkaMaaSClient kafkaClient = client.getKafkaClient();\n```\n\nTo avoid explicit dependency to Kafka clients, maas client only provide various info about Kafka topic:\n* brokers addresses\n* auth mathod\n* name of topic\n* topic options and configs\n\nMaaS Client doesn't provide methods to create KafkaProducer or KafkaConsumer. So developer can freely choose more suitable version of kafka client library for his needs.\nGet or create topic and create KafkaProducer to it: \n```java\n// search existing or request for new topic by MaaS, address structure contains all \n// required info to create connection to Kafka broker instances   \nvar address = kafkaClient.getOrCreateTopic(new Classifier(\"invoices\"), TopicCreateOptions.DEFAULTS);\n\n// transform address to connection properties needed to KafkaProducer/KafkaConsumer instantiation \nvar props = address.formatConnectionProperties()\n    \t.orElseThrow(() -\u003e new IllegalArgumentException(\"Unable to construct connection properties to Kafka\"));\n\n// create KafkaProducer instance \ntry(var producer = new KafkaProducer\u003cInteger, String\u003e(props, new IntegerSerializer(), new StringSerializer())) {\n\t...\n}\n```\n\nProduce record for tenant topics:  \n```java\nTopicAddress topicAddress = kafkaClient.getTopic(new Classifier(\"orders\").tenantId(TenantContext.get()))\n        .orElseThrow(() -\u003e new RuntimeException(\"Topic `orders' not found. Configuration or deployment processing error?\"));\n\nProducerRecord\u003cInteger, String\u003e record = new ProducerRecord\u003c\u003e(\n        topicAddress.getTopicName(),\n        order.getOrderId(),\n        mapper.writeValueAsString(wrapped));\n\n// example how to create KafkaProducer look at the previous code example\nkafkaProducer.send(record);\n```\n\nConsumer for tenant-topics is much complex, because of runtime nature of tenants. Tenant may be created and activated of deactivated in runtime. \nAnd consumer in microservice have to dynamically subscribe/unsubscribe to topics created to new tenants.\n\nMaaSKafkaClient provide convenient method to manage topic subscriptions on tenants list change. Callback is called at least once on application \nstartup to simplify initial microservice subscriptions code.\n```java\nkafkaClient.watchTenantTopics(\"orders\", topics -\u003e {\n            // perform subscribe/unsubscribe to given topics \n        });\n```\n\n### Context propagation\nIt is crucial to save and restore context during message processing. Moreover, its is manadatory requirements to correctly filtering messages in \nBlue/Green deployment. To serialize current execution context into message headers just call utility method:\n```java\nimport com.netcracker.cloud.maas.client.context.kafka.KafkaContextPropagation;\n\nvar record = new ProducerRecord\u003c...\u003e(\n        topicName,\n        partition,\n        messageKey,\n        messageValue,\n        KafkaContextPropagation.propagateContext() // dump context to message headers\n   );\n```\nContext propagation methods is in class [KafkaContextPropagation](kafka-context-propagation/src/main/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagation.java) located in module:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.netcracker.cloud.maas.client\u003c/groupId\u003e\n    \u003cartifactId\u003ekafka-context-propagation\u003c/artifactId\u003e\n\u003c/dependency\u003e\n\n```\n\nTo restore context from received message into current execution thread use:\n```java\nConsumerRecord message = ... \nKafkaContextPropagation.restoreContext(message.headers());\n```\n\n## RabbitMQ client usage example\nAll MaaS operations for RabbitMQ is collected in [RabbitMaaSClient](https://github.com/Netcracker/qubership-maas-client/blob/main/client/src/main/java/com/netcracker/cloud/maas/client/api/rabbit/RabbitMaaSClient.java). \nTo obtain *new* instance of MaaS RabbitMQ client just call:\n```java\nRabbitMaaSClient rabbitClient = client.getRabbitClient();\n```\nDespite of Kafka approach where classifier is pointed to topic, classifier used for rabbit is pointed to VHost entity in RabbitMQ.\nSo to locate or create VHost you need: \n```java\nVHost vhost = rabbitClient.getOrCreateVirtualHost(new Classifier(\"commands\"));\n```\n`VHost` entity contains exhaustive information about vhost location and credentials needed for connection to RabbitMQ instance.\n\nIf you want to just get vhost (without its creation in case it doesn't exist):\n```java\nVHost vhost = client.getVirtualHost(new Classifier(\"commands\"));\n```\n\n### Context propagation \nIn Blue/Green deployments you need to save and restore context information about original request version. Because version exchange \ncreated for `versionedEntities` rely on `version` message header, you need to save http `X-Version` header value to message headers. Also, you need to \nrestore version value to microservice execution context on message receiver side. \n\nMaaS Client offers utility class to simplify these tasks. Include dependency to:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.netcracker.cloud.maas.client\u003c/groupId\u003e\n    \u003cartifactId\u003erabbit-context-propagation\u003c/artifactId\u003e\n    \u003cversion\u003e{version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nTo save version context to message you can use:\n```java\nAMQP.BasicProperties props = new AMQP.BasicProperties();\n\n// save version value to message headers\nprops = RabbitContextPropagation.propagateContext(props);\n\nchannel.basicPublish(\"my-exchange\", routingKey,  props, data);\n```\n\nTo restore context from message to consumer thread: \n```java\nDeliverCallback deliverCallback = (consumerTag, delivery) -\u003e {\n        ....\n        // restore b/g version context from message headers \n\t\tRabbitContextPropagation.restoreContext(delivery);\n        ...\n}\n```\n\n## Migration\nDetails [here](/docs/migration)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetcracker%2Fqubership-maas-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetcracker%2Fqubership-maas-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetcracker%2Fqubership-maas-client/lists"}