Discovery services

How to create and manage a discovery service.

Key takeaways

MemoryDiscovery Component used to create discovery services that keep data in memory.
Configure Method used to configure a MemoryDiscovery component.
Register Method used to add connection parameters to a MemoryDiscovery component.
resolveOne Method used to obtain a set of connection parameters identified by a common key.
resolveAll Method used to obtain all sets of connection parameters identified by a common key.

Introduction

In this tutorial, you will learn how to create and operate a discovery service that stores connection parameters in memory. We will begin by explaining the necessary pre-requisites. Then, we will continue by showing how to create the service and add and extract connection parameters from it. We will finish with a comprehensive example that illustrates all the learned concepts.

Pre-requisites

To create a discovery service, we can use the MemoryDiscovery class, which models a discovery service that stores connections in memory. To import this class, we can use the following code:

import { MemoryDiscovery } from "pip-services3-components-nodex";
using PipServices3.Components.Connect;
import (
	cconn "github.com/pip-services3-gox/pip-services3-components-gox/connect"
)
import 'package:pip_services3_components/pip_services3_components.dart';
from pip_services3_components.connect import MemoryDiscovery
Not available

Creating a discovery service

In order to create our discovery service, we need to create an instance of the MemoryDiscovery class. Here, we have two options: we add one or more sets of connection parameters to the constructor through a config object

let config = ConfigParams.fromTuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
);

let discovery = new MemoryDiscovery(config);
var config = ConfigParams.FromTuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
);

var discovery = new MemoryDiscovery(config);

config := cconf.NewConfigParamsFromTuples(
	"key1.host", "10.1.1.100",
	"key1.port", "8080",
	"key2.host", "10.1.1.100",
	"key2.port", "8082",
)

discovery := cconn.NewEmptyMemoryDiscovery()

var config = ConfigParams.fromTuples([
  'key1.host', '10.1.1.100',
  'key1.port', '8080',
  'key2.host', '10.1.1.100',
  'key2.port', '8082'
]);

var discovery = MemoryDiscovery(config);
config = ConfigParams.from_tuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
)

discovery = MemoryDiscovery(config)
Not available

or we add them after instantiation via the configure() method.

let config = ConfigParams.fromTuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
);

let discovery = new MemoryDiscovery();
discovery.configure(config);

var config = ConfigParams.FromTuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
);

var discovery = new MemoryDiscovery();
discovery.Configure(config);

``

config := cconf.NewConfigParamsFromTuples(
	"key1.host", "10.1.1.100",
	"key1.port", "8080",
	"key2.host", "10.1.1.100",
	"key2.port", "8082",
)

discovery := cconn.NewEmptyMemoryDiscovery()
discovery.Configure(context.Background(), config)

var config = ConfigParams.fromTuples([
  'key1.host', '10.1.1.100',
  'key1.port', '8080',
  'key2.host', '10.1.1.100',
  'key2.port', '8082'
]);

var discovery = MemoryDiscovery();
discovery.configure(config);

config = ConfigParams.from_tuples(
    "key1.host", "10.1.1.100",
    "key1.port", "8080",
    "key2.host", "10.1.1.100",
    "key2.port", "8082"
)

discovery = MemoryDiscovery()
discovery.configure(config)
``

Not available

Adding connections

Once we have created our component, we can use the register() method to add connections to our discovery service. This method takes the correlationId, a key, and the connection parameters to be registered as inputs. The following example shows how to use this method.

await discovery.register("123", "key3", ConnectionParams.fromTuples(
    "host", "localhost",
    "port", "8000"
)); // Returns {"host": "localhost", "port": "8000"}

discovery.RegisterAsync("123", "key3", ConnectionParams.FromTuples(
    "host", "localhost", 
    "port", "8000"
)).Wait(); // Returns {"host": "localhost", "port": "8000"}

discovery.Register("123", "key3", cconn.NewConnectionParamsFromTuples(
	"host", "localhost",
	"port", "8000",
)) // Returns {"host": "localhost", "port": "8000"}

await discovery.register('123', 'key3', ConnectionParams.fromTuples([
  'host', 'localhost',
  'port', '8000'
])); // Returns {"host": "localhost", "port": "8000"}

discovery.register('123', 'key3', ConnectionParams.from_tuples( 
    'host', 'localhost', 
    'port', '8000' 
)) # Returns {'host': 'localhost', 'port': '8000'}
Not available

Resolving connections

We can obtain a connection with the resolveOne() method, which considers as input parameters the correlationId and the key identifying the connection parameters we are looking for.

let connection = await discovery.resolveOne("123", "key1"); // Returns {'host': '10.1.1.100', 'port': '8080'}
var connection = await discovery.ResolveOneAsync("123", "key1"); // Returns {'host': '10.1.1.100', 'port': '8080'}
connection, _ := discovery.ResolveOne("123", "key1") // Returns {'host': '10.1.1.100', 'port': '8080'}
var connection = await discovery.resolveOne('123', 'key1'); // Returns {'host': '10.1.1.100', 'port': '8080'}
connection = discovery.resolve_one("123", "key1") # Returns {'host': '10.1.1.100', 'port': '8080'}
Not available

Alternatively, we can use the resolveAll() method, which asks for the same inputs, but returns a list containing all the sets of connection parameters identified by a common key.

await discovery.register("123", "key1", ConnectionParams.fromTuples(
    "param1", "val1",
    "param2", "val2"
));

let connection = await discovery.resolveAll("123", "key1"); // Returns {'host': '10.1.1.100', 'port': '8080'}
// Returns [{'host': '10.1.1.100', 'port': '8080'}, {'param1': 'val1', 'param2': 'val2'}]
await discovery.RegisterAsync("123", "key1", ConnectionParams.FromTuples(
    "param1", "val1",
    "param2", "val2"
));

var connections = await discovery.ResolveAllAsync(null, "key1");
// Returns [{'host': '10.1.1.100', 'port': '8080'}, {'param1': 'val1', 'param2': 'val2'}]
discovery.Register("123", "key1", cconn.NewConnectionParamsFromTuples(
	"param1", "val1",
	"param2", "val2",
))

connection, _ := discovery.ResolveAll("123", "key1") 
// Returns [{'host': '10.1.1.100', 'port': '8080'}, {'param1': 'val1', 'param2': 'val2'}]
await discovery.register('123', 'key1', ConnectionParams.fromTuples([
  'param1', 'val1',
  'param2', 'val2'
]));

var connection = await discovery.resolveAll('123', 'key1'); // Returns {'host': '10.1.1.100', 'port': '8080'}
// Returns [{'host': '10.1.1.100', 'port': '8080'}, {'param1': 'val1', 'param2': 'val2'}]
discovery.register('123', 'key1', ConnectionParams.from_tuples( 
    'param1', 'val1', 
    'param2', 'val2' 
)) 

connections = discovery.resolve_all(None, "key1") 
# Returns [{'host': '10.1.1.100', 'port': '8080'}, {'param1': 'val1', 'param2': 'val2'}]
Not available

Complete example

In this section, we have an example that illustrates the use of a memory discovery service, from creation to addition of parameters to resolving a connection. The code is as follows:

// Pre-requisites
import { ConfigParams } from "pip-services3-commons-nodex";
import { ConnectionParams, MemoryDiscovery } from "pip-services3-components-nodex";

export async function main() {
    // Defining the component 
    let config = ConfigParams.fromTuples(
        "key1.host", "10.1.1.100",
        "key1.port", "8080",
        "key2.host", "10.1.1.100",
        "key2.port", "8082"
    );

    let discovery = new MemoryDiscovery();
    discovery.configure(config);

    // Adding more parameters 
    await discovery.register("123", "key1", ConnectionParams.fromTuples(
        "param1", "val1",
        "param2", "val2"
    ));

    await discovery.register("123", "key3", ConnectionParams.fromTuples(
        "host", "localhost",
        "port", "8000"
    ));

    // Resolving connections 
    console.log(await discovery.resolveOne("123", "key1"));
    console.log(await discovery.resolveAll("123", "key1"));
    console.log(await discovery.resolveOne("123", "key3"));
}

Which after running produces the following result:

figure 1

// Pre-requisites
using System;
using PipServices3.Commons.Config;
using PipServices3.Components.Connect;

namespace ExampleApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Defining the component 
            var config = ConfigParams.FromTuples(
                "key1.host", "10.1.1.100",
                "key1.port", "8080",
                "key2.host", "10.1.1.100",
                "key2.port", "8082"
            );

            var discovery = new MemoryDiscovery();
            discovery.Configure(config);

            // Adding more parameters 
            discovery.RegisterAsync("123", "key1", ConnectionParams.FromTuples(
                "param1", "val1",
                "param2", "val2"
            )).Wait();

            discovery.RegisterAsync("123", "key3", ConnectionParams.FromTuples(
                "host", "localhost",
                "port", "8000"
            )).Wait(); 

            // Resolving connections 
            Console.WriteLine(discovery.ResolveOneAsync("123", "key1").Result);
            Console.WriteLine(discovery.ResolveAllAsync("123", "key1").Result);
            Console.WriteLine(discovery.ResolveOneAsync("123", "key3").Result);
        }
    }
}

Which after running produces the following result:

figure 1

package main

// Pre-requisites
import (
	"fmt"

	cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
	cconn "github.com/pip-services3-gox/pip-services3-components-gox/connect"
)

// Runner
func main() {
	config := cconf.NewConfigParamsFromTuples(
		"key1.host", "10.1.1.100",
		"key1.port", "8080",
		"key2.host", "10.1.1.100",
		"key2.port", "8082",
	)

	discovery := cconn.NewEmptyMemoryDiscovery()
	discovery.Configure(context.Background(), config)

	// Adding more parameters
	discovery.Register("123", "key1", cconn.NewConnectionParamsFromTuples(
		"param1", "val1",
		"param2", "val2",
	))

	discovery.Register("123", "key3", cconn.NewConnectionParamsFromTuples(
		"host", "localhost",
		"port", "8000",
	))

	// Resolving connections
	res1, _ := discovery.ResolveOne("123", "key1")
	res2, _ := discovery.ResolveAll("123", "key1")
	res3, _ := discovery.ResolveOne("123", "key3")

	fmt.Println(res1)
	fmt.Println(res2)
	fmt.Println(res3)
}

Which after running produces the following result:

figure 1

// Pre-requisites
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_components/pip_services3_components.dart';

void main(List<String> argument) async {
  // Defining the component 
  var config = ConfigParams.fromTuples([
    'key1.host', '10.1.1.100',
    'key1.port', '8080',
    'key2.host', '10.1.1.100',
    'key2.port', '8082'
  ]);

  var discovery = MemoryDiscovery();
  discovery.configure(config);

  // Adding more parameters 
  await discovery.register('123', 'key3', ConnectionParams.fromTuples([
    'host', 'localhost',
    'port', '8000'
  ])); // Returns {"host": "localhost", "port": "8000"}

  await discovery.register('123', 'key1', ConnectionParams.fromTuples([
    'param1', 'val1',
    'param2', 'val2'
  ]));

  // Resolving connections 
  print(await discovery.resolveOne('123', 'key1'));
  print(await discovery.resolveAll('123', 'key1'));
  print(await discovery.resolveOne('123', 'key3'));
}

Which after running produces the following result:

figure 1

# Pre-requisites
from pip_services3_commons.config import ConfigParams 
from pip_services3_components.connect import MemoryDiscovery, ConnectionParams 
 
# Defining the component 
config = ConfigParams.from_tuples( 
    "key1.host", "10.1.1.100", 
    "key1.port", "8080", 
    "key2.host", "10.1.1.100", 
    "key2.port", "8082" 
) 
 
discovery = MemoryDiscovery() 
discovery.configure(config) 
 
# Adding more parameters    
discovery.register('123', 'key1', ConnectionParams.from_tuples( 
    'param1', 'val1', 
    'param2', 'val2' 
)) 
 
discovery.register('123', 'key3', ConnectionParams.from_tuples( 
    'host', 'localhost', 
    'port', '8000' 
))     
# Resolving connections    
print(discovery.resolve_one("123", "key1")) 
print(discovery.resolve_all("123", "key1"))
print(discovery.resolve_one("123", "key3"))

Which after running produces the following result:

figure 1

Not available

Wrapping up

In this tutorial, we learned how to create a discovery service that stores connection parameters in memory. We also saw how to add a set of connection parameters and extract them from the component. We ended with a complete example that illustrated all the operations that can be performed on this component.