Lesson: Pico to Pico Subscriptions (OLD)

Learning Objectives

After completing this lesson, you will be able to do the following:

  • Explain the purpose of the well-known ECI and how to use it. 
  • Understand pico-to-pico relationships and subscriptions
  • Use the developer tools to manage pico subscriptions
  • Link two or more picos with a subscription programmatically and have them interact. 

Prerequisites 

Completed (Classic) Quickstart lesson.

  • Be able to register and install rulesets

Completed Events & Queries lesson.

  • Be able to create channels.
  • Understand how events are raised on channels

Completed Pico-Based Systems.

  • Understand what a Pico is.
  • Be able to create new child Picos


Subscriptions

Subscriptions allow two picos to communicate with each other on a secure channel. This empowers a Pico to identify events that are safe to react too.

Subscriptions also allow complex structures to be formed from multiple picos. Feel free to read more about subscriptions.

To familiarize our self's with subscriptions we will create a subscription between two child picos.

Create Child Picos

Create two new child Pico's. After logging in and going to home page , navigate to About This Pico web page. Create two new child picos. Feel free to look at Pico-Based Systems for a refresher.

Name the first child ChildA, and second, ChildB.

You should have Two new Picos, which look something like this.

Subscriptions process starts with a well known ECI. Well known eci is a event channel that is only used to receive subscription requests on.

Create Well known ECI

Create a well known eci in ChildA. In About This Pico page navigate your account to ChildA pico.

Well Known ECI is just a channel, so after navigating to ChildA pico go to Channel Manager webpage.

Create a new channel, with name Well_Known and type Pico_Tutorial (don't forget the under scores).

You should have a Well_Known channel that looks similar to this.

COWABUNGA! Now ChildA has a Well_Known ECI.

Request Subscription

We request subscriptions from Well known ECI's. ChildB now can request subscription from ChildA's well known ECI. Open up a new tab in your browser and navigate to your root pico, open up ChildB pico.

In ChildB open up Subscription Manager, click on new Subscription.

Name the subscription brothers , with name Space  Tutorial_Subscriptions,  Channel Type Pico_Tutorial, my_role BrotherB, your_role BrotherA and for Target enter the well_known ECI from ChildA, just ignore attributes for now

Should look something like this.

<make an arrow between the target and well known>

After double checking that you entered the correct target and subscriptions profiling information press Subscribe.

This will send a subscription request to ChildA from ChildB on ChildA's Well Known ECI.

Both ChildA and ChldB will create a channel for the pending subscription. If the pending subscription is accepted by ChildA, these channels will be exchanged and will serve as secure communication Channels between the two Pico's.

If you check your Channel Manager you will see the new channels from the pending subscription.

Subscription Management will show you your pending subscriptions.

Notice that ChildA pending subscription has an event channel, this is ChildB subscription channel. When ChildA accepts the pending subscription, ChildA will send the subscription accept event on this channel.

Accept Subscription

On ChildA, Approve the pending subscription titled brothers.

Upon subscription acceptance ChildA raises a subscription approved event to ChildB on ChildB's pending subscription channel. ChildA attaches its own pending subscription channel to the event, this is how ChildB obtains ChildA subscription channel.  Both Picos then update there pending subscriptions to subscribed. (NOTE: The eci in the event channel is the channel to the other pico in the subscription, you can view your subscription channel in channel management. Back channel and Attributes is still under development. Back channel is the event channel of the other subscription holder. Back channel can be used to correlate incoming events with subscription. below is an updated subscription with back channels being displayed.

Programmatically

To do this a parent pico will create two children, install rules in the children, children will create well known channel, children will notify parents of channel creation, parent will initialize subscriptions between children.

Create 2 new rulests, one for the parent and one for the child pico. Name them parent_sub and child_sub.

In global block create a structure to hold new pico children names. create children will use a foreach to create theses children.

global{  
  children = ["ChildC","ChildD"];  // children to be created
 }


In parent_sub ruleset create two rules, one for creating children and one for requesting a subscription between the children. Create child provides the rule to be installed in the child, you need to update your code after you register child_sub rule with this rid.

// create 2 children 
    rule createChildren{
    select when subscriptions automate
    foreach children setting (child)
    pre{
      attributes = {}
                              .put(["Prototype_rids"],<child_sub rid as a string>) // ; separated rulesets the child needs installed at creation
                              .put(["name"],child) // name for child
                              ;
    }
    {
      event:send({"cid":meta:eci()}, "wrangler", "child_creation")  // wrangler api event.
      with attrs = attributes.klog("attributes: "); // needs a name attribute for child
    }
    always{
      log("create child for " + child);
    }
  }

   // Request Subscription
  rule requestSubscription { // ruleset for parent 
    select when subscriptions child_well_known_created well_known re#(.*)# setting (sibling_well_known_eci) 
            and subscriptions child_well_known_created well_known re#(.*)# setting (child_well_known_eci)
   pre {
      attributes = {}.put(["name"],"brothers")
                      .put(["name_space"],"Tutorial_Subscriptions")
                      .put(["my_role"],"BrotherB")
                      .put(["subscriber_role"],"BrotherA")
                      .put(["subscriber_eci"],child_well_known_eci.klog("target Eci: "))
                      .put(["channel_type"],"Pico_Tutorial")
                      .put(["attrs"],"success")
                      ;
	}
	{
		event:send({"cid":sibling_well_known_eci.klog("sibling_well_known_eci: ")}, "wrangler", "subscription")
			with attrs = attributes.klog("attributes for subscription: ");
	}
    always{ 
      log("send child well known " +sibling_well_known_eci+ "subscription event for child well known "+child_well_known_eci); 
    }
} 

In child_sub ruleset create two rules one that creates a well known channel and one that notifies parent of the creation.

This rule should select on wrangler init_events event. This will be raised right after the parent has installed the needed rulesets in this child.

  rule createWellKnown {
    select when wrangler init_events
    pre {
      attr = {}.put(["channel_name"],"Well_Known")
                      .put(["channel_type"],"Pico_Tutorial")
                      .put(["attributes"],"")
                      .put(["policy"],"")
                      ;
    }
    {
        event:send({"cid": meta:eci()}, "wrangler", "channel_creation_requested")  
        with attrs = attr.klog("attributes: ");
    }
    always {
      log("created wellknown channel");
    }
  }

Well known created will send an event to parent, notifying the parent their ready to participate in a subscription.

Warning: The event this rule raises (subscriptions child_well_known_created with well_known = <well_known_eci>) may fail to be raised so you will need to manually raise it for each child.
  rule wellKnownCreated {
    select when wrangler channel_created where channel_name eq "Well_Known" && channel_type eq "Pico_Tutorial"
    pre {
        // find parent 
        parent_results = wrangler_api:parent();
        parent = parent_results{'parent'};
        parent_eci = parent[0].klog("parent eci: ");
        well_known = wrangler_api:channel("Well_Known").klog("well known: ");
        well_known_eci = well_known{"cid"};
        init_attributes = event:attrs();
        attributes = init_attributes.put(["well_known"],well_known_eci);
    }
    {
		event:send({"cid":parent_eci.klog("parent_eci: ")}, "subscriptions", "child_well_known_created")
    		with attrs = attributes.klog("event:send attrs: ");
    }
    always {
      log("parent notified of well known channel");
    }
  }

Register your rulesets update the bootstrap rid in parent_sub, flush and install. Raise subscriptions automate event to your parent pico.

You should see ChildC and ChildD newly created.

Navigate to ChildD channel manager to check for created channels channels. If only Well_Known exist in Pico_Tutorial tab, your parent pico failed to see the child_well_known_created event and you will have to raise this event for both children ether manually or by recreating the Well_known in both children.

subscriptions should look like this.

ChildC

ChildD

Notice that the target channel is the same as ChildC's well_known channel.

raise wrangler pending_subscription_approval event with the name of the channel in this case "Tutorial_Subscriptions:Band-Aid". Since subscriptions are stored inside channel attributes you will need to look at channel manager to find the correct channel name.

After the wrangler pending_subscription_approval event you should now see.

To get all subscriptions a pico has, use the subscriptions function like below, with "use module v1_wrangler alias wranglerOS", in meta block.

results = wranglerOS:subscriptions();
subscriptions = results{"subscriptions"};

To remove a subscription raise wrangler subscription_cancellation event with channel_name attribute set to the channel name of the subscription you want to cancel. This well cause both picos to remove their subscription.

Copyright Picolabs | Licensed under Creative Commons.