Command set

How to create and use a CommandSet component.

Key takeaways

CommandSet Component used to group a set of commands.
Command Component used to call a method or a function.
Event Component used to send a notification to one or more listeners.

Introduction

The CommandSet component allows us to group a set of commands and events, which can be called and executed at a later stage.

In this tutorial, you will learn how to create a CommandSet component, add commands and events to it, and perform some operations, such as executing or finding a specific command from a command set.

In order to do this, we divide the work into two sections: the first explains how to operate with commands and the second how to work with events in a CommandSet.

Pre-requisites

In order to use the CommandSet component, we need to import it first. The following command shows how to do this:

import { CommandSet } from "pip-services4-rpc-node";
Not available
import (
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)
Not available
from pip_services4_rpc.commands import CommandSet
Not available

Defining a CommandSet

In order to create a CommandSet component, we need to either create an instance of this class:

let myCommandSetA = new CommandSet();

Not available
import (
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)

myCommandSetA := ccmd.NewCommandSet()
Not available
my_command_setA = CommandSet()
Not available

or define a subclass of it:

export class MyCommandSet extends CommandSet {
    public constructor() {
        super();
    }
}
Not available
type MyCommandSet struct {
	*ccmd.CommandSet
}
Not available
class MyCommandSet(CommandSet):
    _service = None
    def __init__(self, service):
        super(MyCommandSet, self).__init__()
Not available

Using a CommandSet with Commands

In this section, we will learn how to add commands to a command set, and how to retrieve these commands and execute them

Adding a command

We can add a command to the set with the add_command() method. The following example shows how to add a command that, once executed, prints ‘command 1’.

import { Parameters } from "pip-services4-components-node";
import { CommandSet, ICommand, Command } from "pip-services4-rpc-node";


export class MyCommandSet extends CommandSet {
    public constructor() {
        super();
        this.addCommand(this.command1());
    }

    private command1(): ICommand {
        return new Command("command1",
                null,
                (correlationId: string, args: Parameters) => {
                console.log("command 1");
                return null;
            }
        );
    } 
}
Not available
import (
	"context"
	"fmt"

	cexec "github.com/pip-services4/pip-services4-go/pip-services4-components-go/exec"
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)

type MyCommandSet struct {
	*ccmd.CommandSet
}

func NewMyCommandSet() *MyCommandSet {
	c := &MyCommandSet{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddCommand(c.command1())
	return c
}

func (c *MyCommandSet) command1() ccmd.ICommand {
	return ccmd.NewCommand(
		"command1",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 1")
			return
		},
	)
}
Not available
class MyCommandSet(CommandSet):
    _service = None

    def __init__(self, service):
        super(MyCommandSet, self).__init__()
        self.add_command(self._command1())
        
    def _command1(self):
        def handler(context, args):
            return print("command 1")
        return Command("command1",None,handler)
Not available

Adding several commands at once

We can also add several commands at once via the addCommands() method, which accepts as input a list with the names of the methods to be added. In the example below, we add two commands to the set.

export class MyCommandSet extends CommandSet {
    public constructor() {
        super();
        this.addCommands([this.command2(), this.command3()]);
    }

    private command2(): ICommand {
        return new Command("command2",
            null,
            (correlationId: string, args: Parameters) => {
                console.log("command 2");
                return null;
            }
        );
    }

    private command3(): ICommand {
        return new Command("command3",
            null,
            (correlationId: string, args: Parameters) => {
                console.log("command 2");
                return null;
            }
        );
    }
}
Not available
import (
	"context"
	"fmt"

	cexec "github.com/pip-services4/pip-services4-go/pip-services4-components-go/exec"
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)

type MyCommandSet struct {
	ccmd.CommandSet
}

func NewMyCommandSet() *MyCommandSet {
	c := &MyCommandSet{
		CommandSet: *ccmd.NewCommandSet(),
	}

	c.AddCommands([]ccmd.ICommand{c.command2(), c.command3()})
	return c
}

func (c *MyCommandSet) command2() ccmd.ICommand {
	return ccmd.NewCommand(
		"command2",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 2")
			return
		},
	)
}

func (c *MyCommandSet) command3() ccmd.ICommand {
	return ccmd.NewCommand(
		"command3",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 3")
			return
		},
	)
}
Not available
class MyCommandSet(CommandSet):
    _service = None

    def __init__(self, service):
        super(MyCommandSet, self).__init__()
        self.add_commands([self._command2(),self._command3()])
    
    def _command2(self):
        def handler(context, args):
            return print("command 2")
        return Command("command2",None,handler)
   
    def _command3(self):
        def handler(context, args):
            return print("command 3")
        return Command("command3",None,handler) 
Not available

Adding a command set

Alternatively, we can add a CommandSet containing one or more commands. This can be done with the addCommandSet() method. The following example shows how to do this:


export class MyCommandSetB extends CommandSet {
    public constructor() {
        super();
        this.addCommand(this.command1B());
    }

    private command1B(): ICommand {
        return new Command(
            "command1B",
            null, 
            async (correlationId: string, args: Parameters) => {
                console.log("command 1B");
            }
        );
    }
}
    
export class MyCommandSet extends CommandSet {
    private _commandSet = new MyCommandSetB();

    public constructor() {
        super();
        this.addCommandSet(this._commandSet);
    }
}
Not available
type MyCommandSetB struct {
	*ccmd.CommandSet
}

func NewMyCommandSetB() *MyCommandSetB {
	c := &MyCommandSetB{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddCommand(c.command1B())
	return c
}

func (c *MyCommandSetB) command1B() ccmd.ICommand {
	return ccmd.NewCommand(
		"command1B",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 1B")
			return
		},
	)
}

type MyCommandSet struct {
	*ccmd.CommandSet
}

func NewMyCommandSet() *MyCommandSet {
	c := &MyCommandSet{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddCommandSet(NewMyCommandSetB().CommandSet)
	return c
}
Not available
class MyCommandSetB(CommandSet):
    _service = None
    def __init__(self, service):
        super(MyCommandSetB, self).__init__()
        self.add_command(self._command1B())
        
    def _command1B(self):
        def handler(context, args):
            return print("command 1B")
        return Command("command1B",None,handler)
    
class MyCommandSet(CommandSet):
    _service = None
    _command_set = MyCommandSetB(None)
    def __init__(self, context):
        super(MyCommandSet, self).__init__()
        self.add_command_set(self._command_set)
Not available

Executing a command

Once our command set is ready, we can create an instance of it and execute any of the commands it contains with the execute() method. This method accepts as inputs the context, the name of the command to be executed, and the parameters that this command requires.

await mySet.execute(ctx, "command1", null); // Returns command 1
Not available
mySet := NewMyCommandSet()

mySet.Execute(context.Background(), "", "command1", nil) // Returns command 1
Not available
my_set = MyCommandSet(None)

my_set.execute(None, "command1B", None) # Returns command 1B
Not available

Finding a command

We can find a command via the findCommand() method, which accepts the name of the command as input. The next example shows how to use it.

let result = mySet.findCommand("command1");
    
console.log(result.getName());
Not available
result := mySet.FindCommand("command1")

fmt.Println(result.Name()) // Returns 'command1'
Not available
result = my_set.find_command("command1B")

result.get_name() # Returns 'command1B'
Not available

Getting all commands

We can get all the commands available in our command set via the getCommands() method, which returns the results in the form of a list. In the following example, we obtain a list with the commands and then we print their names.

let result2 = mySet.getCommands();

for (let command of result2) {
    console.log(command.getName());
}

// Returns    
// command1
// command2
// command3
// command1B
Not available
result2 := mySet.Commands()

for _, command := range result2 {
	fmt.Println(command.Name())
}

// Returns  
// command1
// command2
// command3
// command1B
Not available
result2 = my_set.get_commands()

for comm in result2:
    print(comm.get_name())
# Returns    
# command1
# command2
# command3
# command1B
Not available

Using a CommandSet with Events

We can also use our command set to store events.

Adding an event

Adding an event is very similar to adding a command and can be done with the addEvent() method. This method accepts the event to be added as input.

export class MyEventSet extends CommandSet {
    public constructor() {
        super();
        this.addEvent(this.event1());
    }

    private event1(): Event {
        return new Event("event1");
    }
}
Not available
type MyEventSet struct {
	*ccmd.CommandSet
}

func NewMyEventSet() *MyEventSet {
	c := &MyEventSet{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddEvent(c.event1())
	return c
}

func (c *MyEventSet) event1() ccmd.IEvent {
	return ccmd.NewEvent("event1")
}
Not available
class MyEventSet(CommandSet):
    _service = None
    _event = None
    def __init__(self, service):
        super(MyEventSet, self).__init__()
        self.add_event(self._event1())

    def _event1(self):
        return Event("event1")
Not available

Adding several events at once

We can also add several commands together with the addEvents() method, which accepts as input a list containing the events to be added. This example explains how to do this:

export class MyEventSet extends CommandSet {
    public constructor() {
        super();
        this.addEvents([this.event2(), this.event3()]);
    }

    private event2(): IEvent {
        return new Event("event2");
    }

    private event3(): IEvent {
        return new Event("event3");
    }
}
Not available
type MyEventSet struct {
	*ccmd.CommandSet
}

func NewMyEventSet() *MyEventSet {
	c := &MyEventSet{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddEvents([]ccmd.IEvent{c.event2(), c.event3()})
	return c
}

func (c *MyEventSet) event2() ccmd.IEvent {
	return ccmd.NewEvent("event2")
}

func (c *MyEventSet) event3() ccmd.IEvent {
	return ccmd.NewEvent("event3")
}
Not available
class MyEventSet(CommandSet):
    _service = None
    _event = None
    def __init__(self, service):
        super(MyEventSet, self).__init__()
        self.add_events([self._event2(),self._event3()])
    
    def _event2(self):
        return Event("event2")
        
    def _event3(self):
        return Event("event3")
Not available

Adding a listener

Additionally, we can add a listener to our command set by using the addListener() method. This method takes the listener as input and adds a listener that is connected to all the events in the command set. In the following example, we add a listener that is connected to event2 and event3.

import { Parameters, Context } from "pip-services4-components-node";
import { CommandSet, IEventListener, IEvent } from "pip-services4-rpc-node";

export class MyListener implements IEventListener {
    onEvent(ctx: Context, event: IEvent, args: Parameters): void {
        console.log("Fired event name " + event.getName());
    }
} 

export class MyEventSet extends CommandSet {
    public constructor() {
        super();
        
        this.addEvents([this.event2(), this.event3()]);
        this.addListener(this.listener1());
    }

    private event2(): IEvent {
        return new Event("event2");
    }

    private event3(): IEvent {
        return new Event("event3");
    }

    private listener1(): IEventListener {
        return new MyListener();
    }
}
Not available
type MyEventSet struct {
	*ccmd.CommandSet
}

func NewMyEventSet() *MyEventSet {
	c := &MyEventSet{
		CommandSet: ccmd.NewCommandSet(),
	}

	c.AddEvents([]ccmd.IEvent{c.event2(), c.event3()})
	c.AddListener(c.listener1())
	return c
}

func (c *MyEventSet) event2() ccmd.IEvent {
	return ccmd.NewEvent("event2")
}

func (c *MyEventSet) event3() ccmd.IEvent {
	return ccmd.NewEvent("event3")
}

func (c *MyEventSet) listener1() ccmd.IEventListener {
	return NewMyListener()
}

type MyListener struct{}

func (c *MyListener) OnEvent(correlationId string, event ccmd.IEvent, value *crun.Parameters) {
	fmt.Println("Fired event " + event.Name())
}

func NewMyListener() *MyListener {
	return &MyListener{}
}
Not available
class MyListener(IEventListener):
    def on_event(self, context, event, args):
        print("Fired event name " + event.get_name())

class MyEventSet(CommandSet):
    _service = None
    _event = None
    def __init__(self, service):
        super(MyEventSet, self).__init__()
        self.add_events([self._event2(),self._event3()])
        self.add_listener(self._listener1())
    
    def _event2(self):
        return Event("event2")
        
    def _event3(self):
        return Event("event3")
    
    def _listener1(self):
        return MyListener()
Not available

Finding an event

We can use the findEvent() method to search for a specific event. This method asks for the event name as input, and if found, returns the event object.


let result4 = myEvents.findEvent("event1");

console.log(result4.getName());  // Returns 'event1'
Not available
result4 := myEvents.FindEvent("event1")

fmt.Println(result4.Name())  // Returns 'event1'
Not available
result4 = my_events.find_event("event2")

result4.get_name()  # Returns 'event2'
Not available

Getting all the events

Finally, similar to the previous method, the getEvents() method allows us to obtain all the events available in our command set in the form of a list. In the example below, we obtain a list with the events, and then, we print their names.

let myEvents = new MyEventSet();

let result3 = myEvents.getEvents();

for (let event of result3)
{
    console.log(event.getName());
}

// Returns:    
// event1
// event2
// event3
Not available

myEvents := NewMyEventSet()

result3 := myEvents.Events()

for _, event := range result3 {
	fmt.Println(event.Name())
}

// Returns:  
// event1
// event2
// event3
Not available
my_events = MyEventSet(None)

result3 = my_events.get_events()

for event in result3:
    print(event.get_name())
# Returns:    
# event2
# event3

Not available

Examples

In this section, we have two examples that show how to work with command sets. The first focus on commands and the second on events.

Example 1

import { Parameters } from "pip-services4-components-node";
import { CommandSet, Command, ICommand } from "pip-services4-rpc-node";

export async function main() { 
    var mySet = new MyCommandSet();

    await mySet.execute(null, "command1", null);
    await mySet.execute(null, "command2", null);
    await mySet.execute(null, "command3", null);
    await mySet.execute(null, "command1B", null);
}


export class MyCommandSetB extends CommandSet {
    public constructor() {
        super();

        this.addCommand(this.command1B());
    }

    private command1B(): ICommand {
        return new Command(
            "command1B",
            null, 
            async (correlationId: string, args: Parameters) => {
                console.log("command 1B");
            }
        );
    }
}

export class MyCommandSet extends CommandSet {
    private _commandSet = new MyCommandSetB();

    public constructor() {
        super();
        this.addCommandSet(this._commandSet);
        this.addCommand(this.command1());
        this.addCommands([this.command2(), this.command3()]);
    }

    private command1(): ICommand {
        return new Command("command1",
                null,
                (correlationId: string, args: Parameters) => {
                console.log("command 1");
                return null;
            }
        );
    } 

    private command2(): ICommand {
        return new Command("command2",
            null,
            (correlationId: string, args: Parameters) => {
                console.log("command 2");
                return null;
            }
        );
    }

    private command3(): ICommand {
        return new Command("command3",
            null,
            (correlationId: string, args: Parameters) => {
                console.log("command 2");
                return null;
            }
        );
    }
}
Not available
package main

import (
	"context"
	"fmt"

	cexec "github.com/pip-services4/pip-services4-go/pip-services4-components-go/exec"
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)

func main() {

	mySet := NewMyCommandSet()

	mySet.Execute(context.Background(), "command1", nil)
	mySet.Execute(context.Background(), "command2", nil)
	mySet.Execute(context.Background(), "command3", nil)
	mySet.Execute(context.Background(), "command1B", nil)
}

type MyCommandSetB struct {
	ccmd.CommandSet
}

func NewMyCommandSetB() *MyCommandSetB {
	c := &MyCommandSetB{
		CommandSet: *ccmd.NewCommandSet(),
	}

	c.AddCommand(c.command1B())
	return c
}

func (c *MyCommandSetB) command1B() ccmd.ICommand {
	return ccmd.NewCommand(
		"command1B",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 1B")
			return
		},
	)
}

type MyCommandSet struct {
	ccmd.CommandSet
}

func NewMyCommandSet() *MyCommandSet {
	c := &MyCommandSet{
		CommandSet: *ccmd.NewCommandSet(),
	}

	c.AddCommand(c.command1())
	c.AddCommandSet(&NewMyCommandSetB().CommandSet)
	c.AddCommands([]ccmd.ICommand{c.command2(), c.command3()})
	return c
}

func (c *MyCommandSet) command1() ccmd.ICommand {
	return ccmd.NewCommand(
		"command1",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 1")
			return
		},
	)
}

func (c *MyCommandSet) command2() ccmd.ICommand {
	return ccmd.NewCommand(
		"command2",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 2")
			return
		},
	)
}

func (c *MyCommandSet) command3() ccmd.ICommand {
	return ccmd.NewCommand(
		"command3",
		nil,
		func(ctx context.Context, args *cexec.Parameters) (result interface{}, err error) {
			fmt.Println("command 3")
			return
		},
	)
}

Not available
class MyCommandSetB(CommandSet):

    def __init__(self, service):
        super(MyCommandSetB, self).__init__()
        self.add_command(self._command1B())
        
    def _command1B(self):
        def handler(context, args):
            return print("command 1B")
        return Command("command1B",None,handler)

class MyCommandSet(CommandSet):

    _command_set = MyCommandSetB(None)
    def __init__(self, service):
        super(MyCommandSet, self).__init__()
        self.add_command(self._command1())
        self.add_commands([self._command2(),self._command3()])
        self.add_command_set(self._command_set)
        
    def _command1(self):
        def handler(context, args):
            return print("command 1")
        return Command("command1",None,handler)
    
    def _command2(self):
        def handler(context, args):
            return print("command 2")
        return Command("command2",None,handler)
   
    def _command3(self):
        def handler(context, args):
            return print("command 3")
        return Command("command3",None,handler)  
    
mySet = MyCommandSet(None)

mySet.execute(None, "command1", None)
mySet.execute(None, "command2", None)
mySet.execute(None, "command3", None)
mySet.execute(None, "command1B", None)

Not available

Example 2


import { Parameters, Context } from "pip-services4-components-node";
import { CommandSet, IEventListener, IEvent } from "pip-services4-rpc-node";

// Step 1 - Create the command set with events
export class MyEventSet extends CommandSet {
    public constructor() {
        super();
        this.addEvent(this.event1());
        this.addEvents([this.event2(), this.event3()]);
        this.addListener(this.listener1());
    }

    private event1(): IEvent {
        return new Event("event1");
    }

    private event2(): IEvent {
        return new Event("event2");
    }

    private event3(): IEvent {
        return new Event("event3");
    }

    private listener1(): IEventListener {
        return new MyListener();
    }
}

// Step 2 - Create a listener
export class MyListener implements IEventListener {
    onEvent(ctx: Context, event: IEvent, args: Parameters): void {
        console.log("Fired event name " + event.getName());
    }
} 


// Step 3  - Create an instance of the command set
let myEvents = new MyEventSet();

// Step 4 - Obtain events
let event1 = myEvents.findEvent("event1");
let events = myEvents.getEvents();  // Returns a list with event1, event2 and event3

// Step 5 - Select event1 (first element in the list)
let event2 = events[1];  // Returns event1

// Step 6 - Notify the listener of an event occurrence
event1.notify(ctx, null);
event2.notify(ctx, null);
myEvents.notify(ctx, "event3", null);
Not available
package main

import (
	"context"
	"fmt"

	cexec "github.com/pip-services4/pip-services4-go/pip-services4-components-go/exec"
	ccmd "github.com/pip-services4/pip-services4-go/pip-services4-rpc-go/commands"
)

// Step 1 - Create the command set with events
type MyEventSet struct {
	ccmd.CommandSet
}

func NewMyEventSet() *MyEventSet {
	c := &MyEventSet{
		CommandSet: *ccmd.NewCommandSet(),
	}

	c.AddEvent(c.event1())
	c.AddEvents([]ccmd.IEvent{c.event2(), c.event3()})
	c.AddListener(c.listener1())
	return c
}

func (c *MyEventSet) event1() ccmd.IEvent {
	return ccmd.NewEvent("event1")
}

func (c *MyEventSet) event2() ccmd.IEvent {
	return ccmd.NewEvent("event2")
}

func (c *MyEventSet) event3() ccmd.IEvent {
	return ccmd.NewEvent("event3")
}

func (c *MyEventSet) listener1() ccmd.IEventListener {
	return NewMyListener()
}

// Step 2 - Create a listener
type MyListener struct{}

func (c *MyListener) OnEvent(ctx context.Context, event ccmd.IEvent, value *cexec.Parameters) {
	fmt.Println("Fired event " + event.Name())
}

func NewMyListener() *MyListener {
	return &MyListener{}
}

func main() {
	// Step 3  - Create an instance of the command set
	myEvents := NewMyEventSet()

	// Step 4 - Obtain events
	event1 := myEvents.FindEvent("event1")
	events := myEvents.Events() // Returns a list with event1, event2 and event3

	// Step 5 - Select event1 (first element in the list)
	event2 := events[1] // Returns event1

	// Step 6 - Notify the listener of an event occurrence
	event1.Notify(context.Background(), nil)
	event2.Notify(context.Background(), nil)
	myEvents.Notify(context.Background(), "event3", nil)
}
Not available
from pip_services3_commons.commands import Command, CommandSet, ICommand, IEvent, Event, IEventListener

# Step 1 - Create the command set with events

class my_eventset(CommandSet):

    def __init__(self, controller):
        super(my_eventset, self).__init__()
        self.add_event(self._event1())  
        self.add_events([self._event2(), self._event3()])  
        self.add_listener(self._listener1()) 
        

    def _event1(self):
        event = Event("event1")
        event.add_listener(MyListener())
        return Event("event1")

    def _event2(self):
        event = Event("event2")
        event.add_listener(MyListener())
        return Event("event2")

    def _event3(self):
        event = Event("event3")
        event.add_listener(MyListener())
        return Event("event3")

    def _listener1(self):
        return MyListener()

# Step 2 - Create a listener
class MyListener(IEventListener):
    def on_event(self, correlation_id, event, args):
        print("Fired event with name " + event.get_name())

# Step 3  - Create an instance of the command set
my_events = my_eventset(None)

# Step 4 - Obtain events
event1 = my_events.find_event("event1")
events = my_events.get_events()  # Returns a list with event1, event2 and event3

# Step 5 - Select event1 (first element in the list)
event2 = events[1]  # Returns event1

# Step 6 - Notify the listener of an event occurrence
event1.notify("123", None)
event2.notify("123", None)
my_events.notify("123", 'event3', None)

Not available

Wrapping up

In this tutorial, we have seen how to create a CommandSet that contains commands and events. We have also seen how to extract and use those commands and events and perform some operations with them.