Multiple services?

  • I have been reading through the getting started guide and I think I understand how the two message models work.


    However, I had a quick question about the services. It sounds like topics are mapped to a service. Topics define the "methods" that are exposed by the service. So, my question is, what happens if I start two instances of the same service? When someone sends a message, does it go to both services and then get two responses? Does the last service started win, making the other service non-functional?


    Jeff

  • it will be round-robin : https://opendxl.github.io/open…oc/dxlclient.service.html

    "

    DXL Services are exposed to the DXL fabric and are invoked in a fashion similar to RESTful web services. Communication between an invoking client and the DXL service is one-to-one (request/response).

    Each service is identified by the “topics” it responds to. Each of these “topics” can be thought of as a method that is being “invoked” on the service by the remote client.

    Multiple service “instances” can be registered with the DXL fabric that respond to the same “topics”. When this occurs (unless explicitly overridden by the client) the fabric will select the particular instance to route the request to (by default round-robin). Multiple service instances can be used to increase scalability and fault-tolerance


    "

  • You can control which instance of the service to route to by setting up service zones; the intent is that everything will 'just work' (by round robin'ing within a single service zone) so you don't HAVE to set up service zones. But if you want to, for instance, have an EMEA, NA, and APAC service zones, you can control it so that clients will first look for a service instance inside their zone. It's also hierarchical, so you can set up your zones but not ALL services have to have representation in all zones, the messages will get routed to the 'closest' by hierarchy.

  • Ok, thanks, I think I understand.


    One related question. Is it possible to support multiple instances of a session based service? It sounds like they round robin without having zones. Can I use zones to prevent clients from calling to another instance on the fabric? Or is there another way to create a conversation-based client with a service?

  • Service zones do not apply any restrictions. Their purpose is merely to route service requests to services that are available within the current zone. If a service is not found in that zone, it will look in a parent zone. If multiple services exist in the same zone, they will round-robin.


    You can create conversation-based clients by setting the service_id on the Request message. This will route the message to a specific service instance. The typical pattern is to send the initial request without setting the service identifier. In the initial case, the broker will select the service to invoke. After the initial invocation, the service_id as obtained in the initial Response message is used for all subsequent requests.


    I updated the service example that is included with the OpenDXL Python Client SDK to create multiple services as show below:



    The output from this sample should look similar to the following:


    Python: Multiple Service Output
    1. Service received request payload: ping
    2. Client received response payload: pong from service {1c456f55-e6d2-4b4f-95e2-9011cc609d3b}
    3. Service received request payload: ping
    4. Client received response payload: pong from service {2108df2b-cde1-4773-bbb1-7e8443f44ade}
    5. Service received request payload: ping
    6. Client received response payload: pong from service {78aea342-c740-404e-83fc-6fb2ae6ecd61}
    7. Service received request payload: ping
    8. Client received response payload: pong from service {a5538f3d-d14a-4ccf-92d5-e9e3049e2b27}
    9. Service received request payload: ping
    10. Client received response payload: pong from service {4388a0f8-4908-45e6-af02-eae461602141}


    As show above, all of the service instances are invoked in a round-robin fashion. I then updated the invoking client code portion (show below) to capture the service_id from the initial request and use it on all subsequent requests.




    Once those changes have been made, the output should look similar to the following:


    Python: Single Service Invoked Output
    1. Service received request payload: ping
    2. Client received response payload: pong from service {452ec35e-c31a-412e-95c8-d1ea3dde637d}
    3. Service received request payload: ping
    4. Client received response payload: pong from service {452ec35e-c31a-412e-95c8-d1ea3dde637d}
    5. Service received request payload: ping
    6. Client received response payload: pong from service {452ec35e-c31a-412e-95c8-d1ea3dde637d}
    7. Service received request payload: ping
    8. Client received response payload: pong from service {452ec35e-c31a-412e-95c8-d1ea3dde637d}
    9. Service received request payload: ping
    10. Client received response payload: pong from service {452ec35e-c31a-412e-95c8-d1ea3dde637d}



    As shown above, the same service is invoked even though multiple services are registered with the fabric.


    Hope this helps,

    Chris

  • Ok, got it, thanks. A couple additional questions:


    Are there plans to integrate the service conversation model into the client?


    It looks like the service is still selected round robin. Is there a way to select the service to call? For example I may have multiple versions of a product on the fabric. Is it possible to select the one to use?


    thanks

  • Are there plans to integrate the service conversation model into the client?


    There are no current plans to integrate that pattern, but it is definitely something we could look at in the future. Also, if anyone is feeling ambitious, please fork the client and submit a pull request. :)


    It looks like the service is still selected round robin. Is there a way to select the service to call? For example I may have multiple versions of a product on the fabric. Is it possible to select the one to use?


    You are correct. In my previous code example, the initial service was selected via round-robin. That service was used for all subsequent requests (by obtaining the service_id from the initial response).


    If you would like to invoke a specific instance of a service, you can use the "service registry". The topic /mcafee/service/dxl/svcregistry/query is used to query the service registry. The ability to query the registry is pretty limited at this point. If you pass an empty JSON object you will receive information on all of the services registered. If you specify a serviceType in the JSON object you will receive information on all services of that particular type. For example, you could query for all Threat Intelligence Exchange (TIE) services.


    The following code example registers 3 different services. The first two services are of the same type ("myService"), while the third service is a different type ("anotherService"). The code then performs two different queries on the service registry. The first query returns all services, while the second query returns services of the type, "myService".



    The output for the first query should appear similar to the following:



    The output for the second query should appear similar to the following:



    As you can see there is quite a bit of information on each service. It is also important to note that the service registration information includes a serviceGuid. This value can be specified in the service_id of a request message to invoke that particular service. Other useful information includes metaData which could be used as a means of selecting the service to invoke.


    Hope this helps,

    Chris