{"id":24639392,"url":"https://github.com/inomera/integration-adapters","last_synced_at":"2026-02-23T12:03:50.257Z","repository":{"id":272241858,"uuid":"907548215","full_name":"inomera/integration-adapters","owner":"inomera","description":"HTTP REST / SOAP Integration Adapters For Backends","archived":false,"fork":false,"pushed_at":"2025-01-31T11:36:27.000Z","size":1970,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-06T02:51:13.401Z","etag":null,"topics":["apachehttp","authentication","basic-authentication","bearer-authentication","dynamic-reloading","headers","http-client","integration","jwt-authentication","logging","rest-api","simplehttp","soap-api","springboot","ssl","ssl-certificates","ssl-support"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inomera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-23T20:58:08.000Z","updated_at":"2025-01-31T11:35:04.000Z","dependencies_parsed_at":"2025-01-13T07:28:44.678Z","dependency_job_id":"d9958cdf-5240-4721-8f55-c658747e4ec1","html_url":"https://github.com/inomera/integration-adapters","commit_stats":null,"previous_names":["inomera/integration-adapters"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/inomera/integration-adapters","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inomera%2Fintegration-adapters","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inomera%2Fintegration-adapters/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inomera%2Fintegration-adapters/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inomera%2Fintegration-adapters/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inomera","download_url":"https://codeload.github.com/inomera/integration-adapters/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inomera%2Fintegration-adapters/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29742176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"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":["apachehttp","authentication","basic-authentication","bearer-authentication","dynamic-reloading","headers","http-client","integration","jwt-authentication","logging","rest-api","simplehttp","soap-api","springboot","ssl","ssl-certificates","ssl-support"],"created_at":"2025-01-25T11:11:20.002Z","updated_at":"2026-02-23T12:03:50.219Z","avatar_url":"https://github.com/inomera.png","language":"Java","readme":"# Integration Adapters\n\nThe adapter is a library designed to simplify integration with backend or infrastructure systems.\n\nBy providing a properly configured HTTP client, the library handles critical integration tasks such as data modeling, exception handling, and managing the complexities of REST and SOAP protocols. \nIt abstracts the intricacies of communication with external systems, making it easier to focus on your application logic while ensuring a seamless integration experience.\n\nIt composes two main thin libraries. And also it has aa extension thin library.\n\n**micro-integration**\n\nIt is the framework library of Integration Adapters libraries. \nIt includes common models and interfaces. \nIt has no dependencies other than JDK.\n\n**micro-middleware**\n\nImplementations of micro-integration library are included.\nCalling of Http Client and End services is done through this layer.\nSolutions of common problems such as logging and security are included. \nSpring framework's WebserviceTemplate and RestTemplate are used to abstract http client libraries within itself.\n\n**dynamic-adapter-config-bridge extension**\n\nDynamic Configuration Loader with Pull and Push Models\n\nImplements a dynamic configuration loader leveraging the dynamic-adapter-config-bridge extension. \nThe loader supports both eager and lazy initialization modes, with configurable options for triggers and scheduled updates. \nConfiguration can be loaded and updated dynamically, either during application startup or at runtime, enabling seamless integration and adaptability.\n\n# Compatibility Matrix\n\n| Lib        | Version  | Java Version |\n|------------|----------|--------------|\n| micro-integration      |    1.1.X      | 17           |\n| micro-middleware      |    1.1.X      | 17           |\n| dynamic-adapter-config-bridge      |    1.1.X      | 17           |\n\n\n# Integration Adapters Libraries\n\n![Build](https://github.com/inomera/integration-adapters/workflows/Build/badge.svg)\n\n| Artifact                   | Version                                                                                                                                                                                                                                    |\n|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| micro-integration         | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration/micro-integration/badge.svg?version=1.1.1)](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration/micro-integration)                   |\n| micro-middleware          | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration/micro-middleware/badge.svg?version=1.1.1)](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration/micro-middleware)                   |\n| dynamic-adapter-config-bridge          | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration.ext/dynamic-adapter-config-bridge/badge.svg?version=1.1.1)](https://maven-badges.herokuapp.com/maven-central/com.inomera.integration.ext/dynamic-adapter-config-bridge)                   |\n\n## Architecture\n\nHigh Level Diagram\n\n![Components](files/diagrams/integration-adapters-v1.png)\n\n## Issues\n\n## TODO LIST\n - Changing SSL cert loading (@fatihbozik) : next patch\n - SSL cert, config load from dynamic configs (@fatihbozik) : DONE (1.1.0)\n - Add runtime configs intercepts (@turgaycan, @oransalih) : DONE (1.1.0)\n - Add ssl forge (@fatihbozik) : DONE (1.1.0)\n\n## Capabilities and Technical Details\n\n**Integration Adapters** provide a comprehensive set of capabilities for **both REST and SOAP services**, ensuring **standardized, secure, and manageable** integration processes.  \n\n- **Supported HTTP Clients:**  \n  - **JDK HTTP Client**  \n  - **Apache HttpClient 5**  \n\n- **License:** **MIT Licensed**, open-source, and available via **Maven Central Repository**.  \n\n## **Capabilities**  \n\n### **1. Standardized HTTP Integration Templates (REST \u0026 SOAP)**  \n- **Success and failure scenarios are standardized** for all HTTP integrations (customizable and overridable).  \n- **Input and output data models** are unified within a single framework.  \n\n### **2. Microservice Model Isolation**  \n- The **adapter layer prevents direct imports of generated classes within microservices**.  \n- Ensures service isolation, **allowing independent evolution of integration components**.  \n\n### **3. Code Consistency and Compliance**  \n- Encourages **uniform coding practices across teams**, ensuring maintainability.  \n- Simplifies integration development and minimizes onboarding effort.  \n\n### **4. Dynamic Configuration Management**  \n- **HTTP and adapter parameters can be modified at runtime** without redeployment.  \n- Configuration can be managed via **databases, files, or centralized configuration services**.  \n- **No redeployment required**, enabling agile change management.  \n\n### **5. Advanced HTTP Logging and Monitoring**  \n- Logging levels can be **dynamically configured** and support the following modes:  \n  - **ALL:** Logs **all HTTP requests \u0026 responses** (headers, body, URL).  \n  - **REQ_RES:** Logs **request \u0026 response bodies** and **URL only**.  \n  - **FAILURE:** Logs **only failed HTTP responses** (non-200 status codes).  \n  - **NONE:** Disables logging entirely.  \n\n### **6. Sensitive Data Masking**  \n- Supports **masking of sensitive data** in **HTTP request/response bodies and headers**.  \n- Protects sensitive information such as **credit card numbers, user credentials, and tokens** from logs.  \n\n### **7. Large Payload Handling**  \n- **Selective field-level logging** allows excluding large payloads from logs.  \n- **For instance**, JSON or XML payloads can be **partially logged** while ignoring non-essential fields.  \n\n### **8. Flexible Authentication Mechanisms**  \n- Authentication settings can be **modified at runtime** without requiring redeployment.  \n- Supported authentication types:  \n  - **HTTP Basic Authentication:** Injects dynamically configured credentials into **Authorization headers**.  \n  - **Custom HTTP Header Authentication:** Allows authentication via **custom HTTP headers**.  \n  - **HTTP Bearer Authentication:** Supports **token retrieval and refresh mechanisms**.  \n  - **None:** Default usage without authentication.  \n\n### **9. SSL/TLS Certificate Management**  \n- Supports **Client SSL certificates and Hostname verification**.  \n- Allows both **TrustAll (insecure) mode** and **certificate-based validation**.  \n\n### **10. Semantic Versioning \u0026 CI/CD Compatibility**  \n- Adapter libraries are versioned using **semantic versioning principles**.  \n- Fully **compatible with CI/CD pipelines**, enabling **automated deployment and versioning**.  \n\n---\n\n## **Key Benefits**  \n✅ **Accelerates Development** → Reduces time-to-market by **streamlining integration development**.  \n✅ **Lowers Maintenance Costs** → **Standardized integration processes** simplify debugging and support.  \n✅ **Highly Configurable \u0026 Extensible** → Runtime configuration changes provide **operational flexibility**.  \n✅ **Ensures Security \u0026 Observability** → Supports **data masking and selective logging for compliance**.  \n\nWith these capabilities, **Integration Adapters** empower enterprises to **build secure, scalable, and future-proof integration solutions**. 🚀\n\n## Libraries\n\nThere are two levels of library layers for now.\n\n### micro-integration\n\nThe top of the integration layer of the microservice.\nThere is no dependency without JDK.\nThe layer consists of interfaces, models, utilities and related stuffs.\n\n### micro-middleware\n\nThe second layer of the integration architecture.\nIt consists of the abstractions of integration parts such as http client, spring-ws-core, javax\nvalidation, apache common utility libs.\n\nsecurity, logging, client implementation\n\n## Example adapter implementation\n\nmirket-adapter is the sample adapter implementation.\nPlease check the implementation of the features before asking any questions.\n\n## Protocols\n\n### REST\n\nApache HttpClient 5\nJDK Http Client\nOK HTTP (not implement yet)\n\n### SOAP\n\n### Generation (WSDL2JAVA)\n\nOne of following optionals is for generation. (Choose one of them what your comfort-zone is)\n\n    Apache CXF (optional)\n    AXIS (optional)\n    GRADLE JAXB Plugin (Optional)    \n    JDK 17\n\nStubs are generated via apache cxf library using sh script or gradle task.\n\nYou can find the example shell scripts under the files/scripts directory.\n\nYou can generate client three ways.\nThere are shell scripts under the files/scripts folder that are to provide generating wsdl to java\ncode using axis/cxf.\n\n* 1 - apache cxf\n\n  Download apache binary dist.\n  Config sh script variable values with your path configs\n  Execute sh or bat scripts.\n\n* 2 - axis2\n\n  Download apache binary dist.\n  Config sh script variable values with your path configs\n  Execute sh or bat scripts.\n\nEnabling axis dependencies please add following dependencies to gradle file.\nmirket-adapter has an example of the axis generation.\n\n    //axis\n    implementation \"org.apache.axis2:axis2:${versions.axis2}\"\n    implementation \"org.apache.axis:axis-jaxrpc:${versions.axis2_jaxrpc}\"\n    implementation \"org.apache.axis2:axis2-saaj:${versions.axis2}\"\n    implementation \"org.apache.axis2:axis2-codegen:${versions.axis2}\"\n    implementation \"org.apache.axis2:axis2-adb-codegen:${versions.axis2}\"\n    \n    // axis\n    axis \"org.apache.axis2:axis2:${versions.axis2}\",\n    \"org.apache.axis:axis-jaxrpc:${versions.axis2_jaxrpc}\",\n    \"org.apache.axis2:axis2-codegen:${versions.axis2}\",\n    \"org.apache.axis2:axis2-adb-codegen:${versions.axis2}\",\n    \"javax.activation:activation:${versions.javax_activation}\"\n\n* 3 - gradle jaxb task(will be added) nad gradle axis (genCountryInfoService)\n\nRecommend third way. It is more easy and minimum dependency.\n\n    Gradle clean/build\n    Execute genXXX task.\n\n#### Rest Layer\n\n    Spring rest template\n    Apache HttpClient 5\n    JDK Http Client\n\n#### WS Layer\n\n    Spring webservice template\n    Apache HttpClient 5\n\n## External Adapter (Backend service) Response Pattern\n\nThe generic code of the segmentation should be finalized.\n\nThe codes in the templates below are given as an example.\n\n```json\n{\n  \"status\": {\n    \"code\": \"0\",\n    \"message\": \"Success\"\n  },\n  \"data\": {\n    //generic type \"T\"\n    //Any Object of server success response\n  }\n}\n```\n\n## Exception Cases\n\nThere are three phases to get error.\n\n### client exception\n\n```json\n{\n  \"status\": {\n    \"code\": \"4000\",\n    \"message\": \"Adapter Client Message\"\n    // fixed message\n  }\n}\n```\n\n### server exception\n\ncode : it is originated from server response\nmessage : it is originated from server response\n\n```json\n{\n  \"status\": {\n    \"code\": \"5000\",\n    \"message\": \"Server Message\"\n    //get from server\n  }\n}\n```\n\n### client exception after server response handling\n\n```json\n{\n  \"status\": {\n    \"code\": \"4500\",\n    \"message\": \"Server Response Message Client Handling Exception Message\"\n    // fixed message\n  }\n}\n```\n\n## Example Adapter Usage\n\n- TODO: Create a template project to use it to create new adapter modules.\n- TODO: Explain how to use an example adapter in user project. How to create beans etc.\n\n## Example Adapter Service Creation\n\nSince you need to write an integration code, there should be one class that manages all requests\nthat you need to send to that endpoint. To make it simple to write integration code, this library\nprovides two base adapter classes that you can extend in your integration service\nclass ```RestAdapter``` and ```SoapAdapter```.\n\nLet's say that we have below services.\n\n#### First Service Definition\n\n| Property Name              | Value                                                 | Description                                   |\n|----------------------------|-------------------------------------------------------|-----------------------------------------------|\n| Service Name               | ExampleRestService                                    | User readable name of service                 |\n| Service Type               | REST                                                  | Service api model                             |\n| Service APIs               | /example-rest/first, /example-rest/first/any-sub-path | API urls that exposed by service              |\n| Service Url                | https://api-gw.ourgw.com/example-rest                 | Main url of service that accessible from GW   |\n\n#### Second Service Definition\n\n| Property Name              | Value                                                   | Description                                   |\n|----------------------------|---------------------------------------------------------|-----------------------------------------------|\n| Service Name               | ExampleSoapService                                      | User readable name of service                 |\n| Service Type               | SOAP                                                    | Service api model                             |\n| Service APIs               | /example-soap/second, /example-soap/second/any-sub-path | API urls that exposed by service              |\n| Service Url                | https://api-gw.ourgw.com/example-soap                   | Main url of service that accessible from GW   |\n\nFirst you need to create your service class. After you create it you can override default methods to\ngain some more control.\n\n### Rest Service Usage\n\n#### Creating the example service and overriding default methods:\n\n```java\npublic class ExampleRestService extends RestAdapter\u003cAdapterConfig\u003e {\n\n    // User can override this method to check the response status from the body of response. Sometimes\n    // services can return an incorrect http status which means a response with a successful http\n    // status but an error inside the body.\n    @Override\n    protected AdapterStatus checkStatusDefaultIsHttp200(HttpAdapterResponse\u003c?\u003e httpAdapterResponse) {\n        final FirstServiceResponseContainer responseContainer = (FirstServiceResponseContainer) httpAdapterResponse.body();\n        //check the body data for status, create business failed status if there is any error.\n        if (responseContainer.checkSomeBusinessError()) {\n            return new AdapterResponse\u003c\u003e(AdapterStatus.createStatusFailedAsBusiness());\n        }\n        return AdapterStatus.createSuccess();\n    }\n\n    //User can override this method to add endpoint level default exception handling.\n    @Override\n    protected \u003cT\u003e AdapterResponse\u003cT\u003e handleExceptionWithDefault(Exception e) {\n        if (e instanceof SomeException) {\n            //do something and return a different AdapterResponse.\n        }\n        return super.handleExceptionWithDefault(e);\n    }\n\n}\n\n``` \n\nThere are more detail about creation steps of example service in below. Let's create an api\nintegration method first.\n\n#### How to send request to an endpoint\n\nUse get,post,put,delete or patch method of RestAdapter to send request to the endpoint.\n\n```java\npublic class ExampleRestService extends RestAdapter\u003cAdapterConfig\u003e {\n\n    public AdapterResponse firstOperation(String firstOpParam) {\n        final Map\u003cString, String\u003e headers = new HashMap();\n        headers.put(\"X-Example-Header\", \"random-value\");\n\n        return get(\n                \"/first?firstOpParam=\" + firstOpParam,\n                // api sub url, this will be added to endpointConfig serviceUrl(gateway or direct)\n                headers,  // headers\n                null, // request body ( null for get request)\n                FirstRestResponse.class,// response type \n                httpAdapterResponse -\u003e { // response customizer callback.\n                    final FirstRestResponse first = httpAdapterResponse.body();\n                    if (first.checkSomeBusinessError()) {\n                        return new AdapterResponse\u003c\u003e(AdapterStatus.createStatusFailedAsBusiness());\n                    }\n                    // you should map your response to your model and don't use Json library classes or generated response class dependent classes in your adapter response.\n                    return new AdapterResponse\u003c\u003e(AdapterStatus.createSuccess(),\n                            first.getTheDataYouWantToReturn());\n                });\n    }\n\n}\n\n``` \n\n### Soap Service Usage\n\n#### Creating the example service and overriding default methods:\n\n```java\npublic class ExampleSoapService extends SoapAdapter\u003cAdapterConfig\u003e {\n\n    // User can override this method to check the response status from the body of response. Sometimes\n    // services can return an incorrect http status which means a response with a successful http\n    // status but an error inside the body.\n    @Override\n    protected AdapterStatus checkStatusDefaultIsHttp200(HttpAdapterResponse\u003c?\u003e httpAdapterResponse) {\n        final SecondServiceResponseContainer responseContainer = (SecondServiceResponseContainer) httpAdapterResponse.body();\n        //check the body data for status, create business failed status if there is any error.\n        if (responseContainer.checkSomeBusinessError()) {\n            return new AdapterResponse\u003c\u003e(AdapterStatus.createStatusFailedAsBusiness());\n        }\n        return AdapterStatus.createSuccess();\n    }\n\n    //User can override this method to add endpoint level default exception handling.\n    @Override\n    protected \u003cT\u003e AdapterResponse\u003cT\u003e handleExceptionWithDefault(Exception e) {\n        if (e instanceof SomeException) {\n            //do something and return a different AdapterResponse.\n        }\n        return super.handleExceptionWithDefault(e);\n    }\n\n}\n\n``` \n\nThere are more detail about creation steps of example service in below. Let's create an api\nintegration method first.\n\n\n### How To Instantiate The Http Bean Configuration For The Adapter\n\n```java\npackage com.inomera.middleware.config;\n\nimport com.inomera.integration.config.model.AdapterConfig;\nimport com.inomera.middleware.client.rest.ApacheHttpRestAdapterClient;\nimport com.inomera.middleware.client.rest.SimpleHttpRestAdapterClient;\nimport com.inomera.middleware.client.soap.ApacheHttpSoapAdapterClient;\nimport com.inomera.middleware.client.soap.SimpleSoapAdapterClient;\nimport org.apache.hc.client5.http.classic.HttpClient;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.Scope;\nimport org.springframework.http.client.ClientHttpRequestFactory;\nimport org.springframework.oxm.Marshaller;\nimport org.springframework.oxm.Unmarshaller;\nimport org.springframework.ws.WebServiceMessageFactory;\nimport org.springframework.ws.transport.WebServiceMessageSender;\n\nimport java.util.function.Supplier;\n\n/**\n * Configuration class for HTTP beans.\n */\n@Configuration\npublic class HttpBeanConfiguration {\n\n  public static final String BEAN_APACHE_HTTP_REST_CLIENT_WITH_CONFIG = \"apacheHttpRestClientWithConfig\";\n  public static final String BEAN_APACHE_HTTP_REST_CLIENT = \"apacheHttpRestClient\";\n  public static final String BEAN_APACHE_CUSTOM_HTTP_REST_CLIENT = \"apacheCustomHttpRestClient\";\n  public static final String BEAN_APACHE_CUSTOM_CONFIG_HTTP_REST_CLIENT = \"apacheCustomConfigHttpRestClient\";\n  public static final String BEAN_APACHE_HTTP_REST_CLIENT_WITH_REQUEST_FACTORY = \"apacheHttpRestClientWithRequestFactory\";\n  public static final String BEAN_SIMPLE_HTTP_REST_CLIENT_WITH_CONFIG = \"simpleRestHttpClientWithConfig\";\n  public static final String BEAN_SIMPLE_HTTP_REST_CLIENT = \"simpleHttpRestClient\";\n  public static final String BEAN_SIMPLE_SOAP_CLIENT = \"simpleSoapClient\";\n  public static final String BEAN_APACHE_HTTP_SOAP_CLIENT = \"apacheHttpSoapClient\";\n  public static final String BEAN_APACHE_CUSTOM_HTTP_SOAP_CLIENT = \"apacheCustomHttpSoapClient\";\n  public static final String BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MESSAGE_SENDER = \"apacheHttpSoapClientWithMessageSender\";\n  public static final String BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MARSHALLER = \"apacheHttpSoapClientWithMarshaller\";\n  public static final String BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MARSHALLER_AND_MESSAGE_FACTORY = \"apacheHttpSoapClientWithMarshallerAndMessageFactory\";\n\n\n  //REST BEANS - \u003ceditor-fold desc=\"REST BEANS\"\u003e\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_REST_CLIENT)\n  public ApacheHttpRestAdapterClient apacheHttpRestAdapterClient() {\n    return new ApacheHttpRestAdapterClient();\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_REST_CLIENT_WITH_CONFIG)\n  public ApacheHttpRestAdapterClient apacheHttpRestAdapterClientWithConfig(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc) {\n    return new ApacheHttpRestAdapterClient(configSupplierFunc);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_CUSTOM_HTTP_REST_CLIENT)\n  public ApacheHttpRestAdapterClient apacheCustomHttpRestAdapterClient(HttpClient httpClient) {\n    return new ApacheHttpRestAdapterClient(httpClient);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_CUSTOM_CONFIG_HTTP_REST_CLIENT)\n  public ApacheHttpRestAdapterClient apacheCustomConfigHttpRestAdapterClient(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          HttpClient httpClient) {\n    return new ApacheHttpRestAdapterClient(configSupplierFunc, httpClient);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_REST_CLIENT_WITH_REQUEST_FACTORY)\n  public ApacheHttpRestAdapterClient apacheHttpRestAdapterClientWithReqFactory(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          ClientHttpRequestFactory clientHttpRequestFactory) {\n    return new ApacheHttpRestAdapterClient(configSupplierFunc, clientHttpRequestFactory);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_SIMPLE_HTTP_REST_CLIENT)\n  public SimpleHttpRestAdapterClient simpleHttpRestAdapterClient() {\n    return new SimpleHttpRestAdapterClient();\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_SIMPLE_HTTP_REST_CLIENT_WITH_CONFIG)\n  public SimpleHttpRestAdapterClient simpleHttpRestAdapterClientWithConfig(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc) {\n    return new SimpleHttpRestAdapterClient(configSupplierFunc);\n  }\n\n  //SOAP BEANS - \u003ceditor-fold desc=\"SOAP BEANS\"\u003e\n  @Scope(\"prototype\")\n  @Bean(BEAN_SIMPLE_SOAP_CLIENT)\n  public SimpleSoapAdapterClient simpleSoapAdapterClient(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc, String marshallerContextPath) {\n    return new SimpleSoapAdapterClient(configSupplierFunc, marshallerContextPath);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_SOAP_CLIENT)\n  public ApacheHttpSoapAdapterClient apacheHttpSoapAdapterClient(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          String marshallerContextPath) {\n    return new ApacheHttpSoapAdapterClient(configSupplierFunc, marshallerContextPath);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_CUSTOM_HTTP_SOAP_CLIENT)\n  public ApacheHttpSoapAdapterClient apacheCustomHttpSoapAdapterClient(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          HttpClient httpClient, String marshallerContextPath) {\n    return new ApacheHttpSoapAdapterClient(configSupplierFunc,\n            httpClient, marshallerContextPath);\n  }\n\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MESSAGE_SENDER)\n  public ApacheHttpSoapAdapterClient apacheHttpSoapAdapterClientWithSender(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc, WebServiceMessageSender webServiceMessageSender,\n          String marshallerContextPath) {\n    return new ApacheHttpSoapAdapterClient(configSupplierFunc, webServiceMessageSender,\n            marshallerContextPath);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MARSHALLER)\n  public ApacheHttpSoapAdapterClient apacheHttpSoapAdapterClientWithMarshaller(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          WebServiceMessageSender webServiceMessageSender,\n          Marshaller marshaller,\n          Unmarshaller unmarshaller,\n          String marshallerContextPath) {\n    return new ApacheHttpSoapAdapterClient(configSupplierFunc,\n            webServiceMessageSender, marshaller, unmarshaller, marshallerContextPath);\n  }\n\n  @Scope(\"prototype\")\n  @Bean(BEAN_APACHE_HTTP_SOAP_CLIENT_WITH_MARSHALLER_AND_MESSAGE_FACTORY)\n  public ApacheHttpSoapAdapterClient apacheHttpSoapAdapterClientWitMarshallAndMsgFactory(\n          Supplier\u003cAdapterConfig\u003e configSupplierFunc,\n          WebServiceMessageSender webServiceMessageSender,\n          Marshaller marshaller,\n          Unmarshaller unmarshaller,\n          WebServiceMessageFactory webServiceMessageFactory,\n          String marshallerContextPath) {\n    return new ApacheHttpSoapAdapterClient(configSupplierFunc,\n            webServiceMessageSender, marshaller, unmarshaller, webServiceMessageFactory,\n            marshallerContextPath);\n  }\n\n\n}\n\n\n```\n\n\n### Example Service Bean Configuration\n\n\nUse get,post,put,delete or patch method of RestAdapter to send request to the endpoint.\n\n```java\npackage com.inomera.mirketadapter;\n\nimport static com.inomera.middleware.config.HttpBeanConfiguration.BEAN_APACHE_HTTP_REST_CLIENT_WITH_CONFIG;\nimport static com.inomera.middleware.config.HttpBeanConfiguration.BEAN_APACHE_HTTP_SOAP_CLIENT;\nimport static com.inomera.telco.commons.config.spring.BeanNames.BEAN_CONFIGURATION_HOLDER;\n\nimport com.inomera.adapter.config.bridge.DynamicAdapterConfigDataBridgeSupplierHandler;\nimport com.inomera.integration.config.AdapterConfigDataSupplier;\nimport com.inomera.integration.config.model.AdapterConfig;\nimport com.inomera.middleware.client.rest.ApacheHttpRestAdapterClient;\nimport com.inomera.middleware.client.soap.ApacheHttpSoapAdapterClient;\nimport com.inomera.mirketadapter.rest.MirketAdapter;\nimport com.inomera.mirketadapter.rest.MirketAdapterImpl;\nimport com.inomera.mirketadapter.soap.CountryAdapter;\nimport com.inomera.mirketadapter.soap.CountryAdapterImpl;\nimport com.inomera.telco.commons.config.ConfigurationHolder;\nimport com.inomera.telco.commons.lang.Assert;\nimport generated.countryinfoservice.CountryInfoService;\nimport java.util.function.Supplier;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnClass;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class MirketAdapterBeanConfiguration {\n\n  private static final String CONFIG_MIRKET_KEY = \"config.adapter.mirket.v1\";\n  private static final String CONFIG_COUNTRY_KEY = \"config.adapter.country.v1\";\n\n  final ApplicationContext applicationContext;\n\n  public MirketAdapterBeanConfiguration(ApplicationContext applicationContext) {\n    this.applicationContext = applicationContext;\n  }\n\n  @Bean\n  @ConditionalOnClass(AdapterConfigDataSupplier.class)\n  public MirketAdapter mirketAdapter(AdapterConfigDataSupplier adapterConfigDataSupplier) {\n    Supplier\u003cAdapterConfig\u003e configSupplierFunc = () -\u003e adapterConfigDataSupplier.getConfigV1(\n            CONFIG_MIRKET_KEY);\n    final ApacheHttpRestAdapterClient apacheHttpRestAdapterClient = (ApacheHttpRestAdapterClient) applicationContext.getBean(\n            BEAN_APACHE_HTTP_REST_CLIENT_WITH_CONFIG, configSupplierFunc);\n    Assert.notNull(apacheHttpRestAdapterClient, \"Mirket ApacheHttpRestAdapterClient cannot be NULL\");\n    return new MirketAdapterImpl(configSupplierFunc, apacheHttpRestAdapterClient);\n  }\n\n  @Bean\n  @ConditionalOnClass(AdapterConfigDataSupplier.class)\n  public CountryAdapter countryAdapter(AdapterConfigDataSupplier adapterConfigDataSupplier) {\n    Supplier\u003cAdapterConfig\u003e configSupplierFunc = () -\u003e adapterConfigDataSupplier.getConfigV1(\n            CONFIG_COUNTRY_KEY);\n\n    final ApacheHttpSoapAdapterClient soapAdapterClient = (ApacheHttpSoapAdapterClient) applicationContext.getBean(\n            BEAN_APACHE_HTTP_SOAP_CLIENT, configSupplierFunc, CountryInfoService.class.getPackage().getName());\n    Assert.notNull(soapAdapterClient, \"Country ApacheHttpSoapAdapterClient cannot be NULL\");\n    return new CountryAdapterImpl(configSupplierFunc, soapAdapterClient);\n  }\n\n  @Bean\n  @ConditionalOnClass(ConfigurationHolder.class)\n  public AdapterConfigDataSupplier adapterConfigDataSupplier() {\n    final ConfigurationHolder configurationHolder = (ConfigurationHolder) applicationContext.getBean(\n            BEAN_CONFIGURATION_HOLDER);\n    Assert.notNull(configurationHolder, \"ConfigurationHolder cannot be NULL\");\n    return new DynamicAdapterConfigDataBridgeSupplierHandler(configurationHolder);\n  }\n}\n\n\n``` \n\n### Adapter General Usage Concerns\n\n1. **Separate Models for Generated Code and MS Usage**  \n   Models generated from external sources and those used within the microservice (MS) must be distinct.\n  - For instance, request/response objects specific to the adapter should be created by developers within the adapter package.\n  - Generated models (e.g., from WSDL/XSD) should not be directly used within the MS.\n\n2. **Naming Standards for Adapter Models**\n  - Models for the adapter must adhere to naming conventions. Any naming inconsistencies in the generated models must be corrected within the adapter layer.\n  - Java naming conventions should be followed, and special characters should be avoided in field names.\n\n3. **Adapter Abstraction and Customer Interfaces**\n  - Beside the Soap/Rest Adapter (abstraction), a customer-specific interface for the microservice should be created.\n  - For reference, see sample projects like `example/ms-example`.\n\n4. **Constructor Consistency in Implementation Classes**\n  - Ensure that all capabilities provided by constructors in the `SoapAdapter` class are implemented in the derived class.\n  - These should ideally be achieved with all constructors.\n\n5. **Integration Tests**\n  - Comprehensive integration tests must be included.\n\n6. **WSDL and XSD Files**\n  - WSDL and XSD files must be placed under the `resources` directory.\n  - Avoid referencing WSDL URLs directly in `build.gradle` files.\n\n7. **Generated Files Placement**\n  - Files generated for SOAP should be placed under a dedicated package with a `generated` prefix.\n  - Example: Include these files outside the source code, within a package like `generated.\u003cpackage_name\u003e`.\n  - This step is optional but ensures consistency and separation of concerns.\n\n\n### Dynamic Config Definitions\n\nCommon Config\n\n```json\n{\n  \"key\": \"config.adapter.common.v1\",\n  \"adapterProperties\": {\n    \"logging\": {\n      \"strategy\": \"REQ_RES\",\n      \"sensitiveFields\": [\n      ],\n      \"nonLoggingFields\": [\n      ]\n    },\n    \"headers\": {\n    },\n    \"http\": {\n      \"requestTimeout\": 30000,\n      \"connectTimeout\": 10000,\n      \"idleConnectionsTimeout\": 180000,\n      \"maxConnections\": 10,\n      \"maxConnPerRoute\": 10,\n      \"poolConcurrencyPolicy\": \"LAX\",\n      \"timeToLive\": 60000,\n      \"skipSsl\": true,\n      \"redirectsEnable\": true\n    },\n    \"auth\": {\n      \"type\": \"NONE\"\n    }\n  }\n}\n```\n\nRest Adapter Config\n\n```json\n{\n  \"key\": \"config.adapter.mirket.v1\",\n  \"adapterProperties\": {\n    \"auth\": {\n      \"type\": \"BEARER\",\n      \"username\": \"username\",\n      \"password\": \"password\",\n      \"url\": \"https://www.googleapis.com/oauth2/v4/token\",\n      \"grantType\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n      \"ttl\": 3600000,\n      \"scope\": \"https://www.googleapis.com/auth/cloud-platform\",\n      \"clientId\": \"client_id\",\n      \"clientSecret\": \"client_secret\",\n      \"contentType\": \"application/x-www-form-urlencoded\",\n      \"accept\": \"application/json\",\n      \"tokenJsonPath\": \"$.access_token\"\n    },\n    \"headers\": {\n      \"X-GW-TOKEN\": \"\"\n    },\n    \"http\": {\n      \"requestTimeout\": 30000,\n      \"connectTimeout\": 10000,\n      \"idleConnectionsTimeout\": 60000,\n      \"maxConnections\": 50,\n      \"maxConnPerRoute\": 50,\n      \"poolConcurrencyPolicy\": \"LAX\",\n      \"timeToLive\": 60000,\n      \"skipSsl\": true,\n      \"redirectsEnable\": true\n    },\n    \"logging\": {\n      \"strategy\": \"REQ_RES\",\n      \"sensitiveFields\": [\n        \"Authorization\"\n      ],\n      \"nonLoggingFields\": [\n        \"file\",\n        \"content\"\n      ]\n    },\n    \"url\": \"https://api.mirket.inomera.com/v10/first\"\n  }\n}\n```\n\nSoap Adapter Config\n\n```json\n{\n  \"key\": \"config.adapter.country.v1\",\n  \"adapterProperties\": {\n    \"logging\": {\n      \"strategy\": \"REQ_RES\",\n      \"sensitiveFields\": [\n        \"Authorization\",\n        \"X-GW-TOKEN\"\n      ],\n      \"nonLoggingFields\": [\n        \"file\",\n        \"content\"\n      ]\n    },\n    \"url\": \"http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso\",\n    \"headers\": {\n      \"SOAPAction\": \"CountryNameResponse\"\n    },\n    \"http\": {\n      \"requestTimeout\": 30000,\n      \"connectTimeout\": 10000,\n      \"idleConnectionsTimeout\": 60000,\n      \"maxConnections\": 50,\n      \"maxConnPerRoute\": 50,\n      \"poolConcurrencyPolicy\": \"LAX\",\n      \"timeToLive\": 60000,\n      \"skipSsl\": true,\n      \"redirectsEnable\": true\n    },\n    \"auth\": {\n      \"type\": \"BASIC\",\n      \"username\": \"inomera\",\n      \"password\": \"inomera\"\n    }\n  }\n}\n```\n\n## Configuring SSL with PEM-encoded Certificates\n\nTo configure SSL in our integration adapters using PEM-encoded certificates, add the following properties to your\n`settings.properties` file:\n\n### Example Configuration\n\nFor embedding an SSL certificate in a keystore:\n\n```properties\nconfig.adapter.mirket.v1={\\\n  ...,\\\n  \"http\": {\\\n    ...,\\\n    \"skipSsl\": false,\\\n    \"ssl\": {\\\n      \"pem\": {\\\n        \"truststore\": {\\\n          \"certificate\": \"file:/Users/johndoe/mirket-certs/*\"\\\n        },\\\n        \"keystore\": {\\\n          \"certificate\": \"file:/Users/johndoe/mirket-certs/*\",\\\n          \"privateKey\": \"file:/Users/johndoe/mirket-certs/private/application.key\",\\\n          \"privateKeyPassword\": \"your_private_key_password_here\"\\\n        }\\\n      }\\\n    },\\\n    ...\\\n  },\\\n  ...\\\n}\n```\n\n### Configuration Details\n\n- `truststore.certificate`: This property accepts a glob pattern to match all certificate files. The certificates\n  matched by the pattern will be combined into the truststore.\n- `keystore.certificate`: Path to the PEM-encoded certificate file.\n- `keystore.privateKey`: Path to the PEM-encoded private key file.\n- `keystore.privateKeyPassword`: Password used to decrypt the private key, if it is encrypted.\n- `skipSsl`: Set to `false` to enable SSL.\n\n### Using PEM Content Directly\n\nPEM content can also be used directly for both the `certificate` and `privateKey` properties. If the property values contain `BEGIN` and `END` markers, they will be treated as PEM content rather than a resource location.\n\n```properties\nconfig.adapter.mirket.v1={\\\n  ...,\\\n  \"http\": {\\\n    ...,\\\n    \"skipSsl\": false,\\\n    \"ssl\": {\\\n      \"pem\": {\\\n        \"truststore\": {\\\n          \"certificate\": \"-----BEGIN CERTIFICATE-----\\nMIID1zCCAr+gAwIBAgIUNM5QQv8IzVQsgSmmdPQNaqyzWs4wDQYJKoZIhvcNAQEL\\nBQAwezELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCVN0YXRlTmFtZTERMA8GA1UEBwwI\\n... (rest of certificate content) ...\\n-----END CERTIFICATE-----\"\\\n        },\\\n        \"keystore\": {\\\n          \"certificate\": \"-----BEGIN CERTIFICATE-----\\nMIID1zCCAr+gAwIBAgIUNM5QQv8IzVQsgSmmdPQNaqyzWs4wDQYJKoZIhvcNAQEL\\nBQAwezELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCVN0YXRlTmFtZTERMA8GA1UEBwwI\\n... (rest of certificate content) ...\\n-----END CERTIFICATE-----\",\\\n          \"privateKey\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD... (rest of private key content) ...\\n-----END PRIVATE KEY-----\",\\\n          \"privateKeyPassword\": \"your_private_key_password_here\"\\\n        }\\\n      }\\\n    },\\\n    ...\\\n  },\\\n  ...\\\n}\n```\n\nThis configuration ensures that SSL is set up using PEM-encoded certificates and private keys, and the settings are read from a JSON value in the `settings.properties` file.\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finomera%2Fintegration-adapters","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finomera%2Fintegration-adapters","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finomera%2Fintegration-adapters/lists"}