FacetScript Language

FacetScript Language Keywords

Keyword Related syntaxExamples                                                                                                       

NewFacetInstance

Create and activate new facet instance

 

<NewFacetInstance fid="file" name="File" type="SffHttpStaticFileFacet">

  <OnActivate>

    <Process BasePath="web" Resource="res"/>

  </OnActivate>

</NewFacetInstance>

DelFacetInstance

Deactivate and remove facet instance

 <NewFacetInstance fid="udps" name="UdpServer" type="SffTcpFacet">
  <OnActivate>
    <NewFacetInstance name="UdpServerImp" type="SffTcpFacet">
      <OnActivate>
        <CreatePipeline url="udp://239.255.42.99:48569"/>
        <!-- Administratively-Scoped Multicast from 239.255/16 range -->
      </OnActivate>
      <OnRequest>
        <DoResponse target="[:fid:]:*">
          <!-- pass to WS facade -->
          <Process>
            <Message>
              <Value>
                <Include>$Request</Include>
                <!-- nest original message to show attributes -->
              </Value>
            </Message>
          </Process>
        </DoResponse>
      </OnRequest>
      <OnResponse>
        <Process>
          <Include>$Request</Include>
          <!-- use original message if not nested -->
          <Include>$Request.Message.Value</Include>
          <!-- unpack nested message with attributes if given -->
        </Process>
      </OnResponse>
    </NewFacetInstance>
  </OnActivate>
  <OnDeactivate>
    <DelFacetInstance name="UdpServerImp"/>
  </OnDeactivate>
  <OnOpen ModifyPipeline="WsServerExtensionArgs"/>
  <OnRequest>
    <DoResponse target="[:fid:].UdpServerImp:*"/>
    <!-- pass to UDP server implementation -->
  </OnRequest>
</NewFacetInstance>

NewPackage

Process and deploy new package (i.e. a collection of related facet instances)

 <NewPackage name="UsbTest">
  <NewFacetInstance fid="usb" name="usb" type="SffTcpFacet">
    <OnActivate>
      <CreatePipeline arguments="RxTxServerExtensionArgs" BaudRate="2400" StopChar="0x0D"/>
    </OnActivate>
    <OnRequest>
      <DoResponse target="usbws:*" process="$Request"/>
    </OnRequest>
  </NewFacetInstance>
  <NewFacetInstance fid="usbws" name="usbws" type="SffTcpFacet">
    <OnOpen>
      <SetDefault>
        <OnRequest>
          <Messagexmlns="http://SFF"/>
        </OnRequest>
      </SetDefault>
      <ModifyPipeline arguments="WsServerExtensionArgs"/>
    </OnOpen>
    <OnRequest>
      <DoResponse target="usb:*" process="$Request"/>
    </OnRequest>
  </NewFacetInstance>
</NewPackage>

name

Facet instance name. Names can be used to refer to facet instances from within facet script. Note that local facets (i.e. facet instances defined within other facets) do not have facet IDs and can be only referenced by their names

 

<Macro Name="executeQuery">

  <Argument>

    <QueryString>

      <Query />

    </QueryString>

  </Argument>

  <Result>

    <DoRequest target="[:RuntimeParams.FacetIDName:]">

      <Process>

        <Message>

          <Value>[:$Macro.Argument.QueryString:]</Value>

        </Message>

      </Process>

    </DoRequest>

  </Result>

</Macro>

fid

Facet ID. The most important facet instance’s attribute. All global facet instances are accessible only via their IDs. Facet IDs also can be used to reference facet instance from within facet script (i.e. from another facet instance)

 

<Macro Name="executeQuery">

  <Argument>

    <QueryString>

      <Query />

    </QueryString>

  </Argument>

  <Result>

    <DoRequest target="[:RuntimeParams.FacetID:]">

      <Process>

        <Message>

          <Value>[:$Macro.Argument.QueryString:]</Value>

        </Message>

      </Process>

    </DoRequest>

  </Result>

</Macro>

type

Facet type. This must resolve to a java class implementing Facet Service interface. The concrete way how mapping is done is implementation dependent. SFF engine uses java simple class names to map to classes

 

Message        → SffMsgFacet            → Generic Message Communication.

Network          → SffNetworkFacet      → TQLEngine cluster support. Define the list of TQLEngine(s) that  can participate in syncing their data

Tql                   → SffTqlFacet             → Thing Query Language Support (Thing Definition, Thing Interaction)

Workflow          →   SffWdlFacet         → Workflow Language Support

Behavior Trees → SffBdlFacet            → Behavior Tree Implementation

Topic                 → SffTopicFacet         → Subscription and Notification of Model changes

Scheduling        →  SffSequenceFacet  → Schedule tasks / jobs (piece of Model code) to be executed in a repeated sequence of defined interval.

Static Files        → SffStaticFileFacet     → Serve static files using TQLEngine.

OnActivate

OnOpen

OnRequest

OnResponse

OnClose

OnDeactivate

Facet lifecycle events entries. Each entry contains a facet script to execute upon the event

 <NewFacetInstance fid="google" name="proxy" type="SffProxyFacet">
  <OnOpen>
    <Process host="www.google.com" port="80"/>
  </OnOpen>
  <OnRequest process="host"/>
</NewFacetInstance>

Process

Specifies actual event method argument. Argument can be either a primitive value or a data structure

 <NewFacetInstance fid="seq" name="seq" type="SffSequenceFacet">
  <OnActivate>
    <DoRequest>
      <Process>
        <Message type="xml">
          <Value>
            <Execute eid="test" schedule="[30../10sec]" limit="15">
              <Action>
                <JavaScript>sffLog.info("Trigger= \n%s", sffContext.processTemplate("$Trigger"));</JavaScript>
              </Action>
            </Execute>
          </Value>
        </Message>
      </Process>
    </DoRequest>
  </OnActivate>
  <OnOpen ModifyPipeline="WsServerExtensionArgs"/>
</NewFacetInstance>

ModifyPipeline

Modifies underlying Netty pipeline with given set of handlers. This is often used to configure a generic pipelines to a specific protocol (e.g. HTTP or WebSocket)

 <NewFacetInstance fid="sensity" name="sensity" type="SffTcpFacet">
  <OnOpen>
    <ModifyPipeline arguments="HttpServerExtensionArgs"/>
    <Process Client.Host="procyon.sensity.com" Client.Port="443"/>
    <ModifyPipeline arguments="HttpsClientExtensionArgs"/>
  </OnOpen>
  <OnRequest process="host"/>
</NewFacetInstance>

CreatePipeline

Creates a “fake” Netty pipeline (i.e. a pipeline not associated with an incoming request). Such pipelines are used to work with internal event sources like timer or USB reader, for example

 <NewFacetInstance fid="udpc" name="UdpClient" type="SffTcpFacet">
  <OnOpen ModifyPipeline="WsServerExtensionArgs">
    <CreatePipeline url="udp://255.255.255.255:48569" as="ClientPipeline" CascadeClosure="true"/>
  </OnOpen>
  <OnRequest>
    <DoRequest>
      <Process>
        <Include>$Request</Include>
        <!-- use original message if not nested -->
        <Include>$Request.Message.Value</Include>
        <!-- unpack nested message with attributes if given -->
      </Process>
    </DoRequest>
  </OnRequest>
</NewFacetInstance>

SetDefault

Set default message attributes

 <NewFacetInstance fid="wsmq" name="wsmq" type="SffTcpFacet">
  <OnOpen>
    <SetDefault>
      <OnRequest>
        <Messagexmlns="http://MQQ"/>
      </OnRequest>
    </SetDefault>
    <ModifyPipeline arguments="WsServerExtensionArgs"/>
    <Process>
      <Client host="107.170.235.20" port="15674"/>
    </Process>
    <ModifyPipeline arguments="WsStompClientExtensionArgs" uri="/stomp/websocket"/>
  </OnOpen>
</NewFacetInstance>

 

Other constructs

Construct SyntaxExample
If-Then-Else  

<if condition="$Request/URI = 'favicon.ico'">

  <then>

    <DoRequest target="file"/>

  </then>

  <else>

    <DoResponse>

      <Process>

        <Message type="xml">

          <Value>

            <Echo>

              <Random>

                [:[:@RT:]$JexlScript:(math:random()):]

              </Random>

              <RequestCount>

                [:$PolicyData.MyMetering.RequestCount:]

              </RequestCount>

              <Include>

                $Request

              </Include>

            </Echo>

          </Value>

        </Message>

      </Process>

    </DoResponse>

  </else>

</if>

Select-Case  

<select by="[:$Request.URI:]">

  <case when="favicon.ico">

    <DoRequest target="file"/>

  </case>

  <default>

    <DoResponse>

      <Process>

        <Message type="xml">

          <Value>

            <Echo>

              <RequestCount>

                [:$PolicyData.MyMetering.RequestCount:]

              </RequestCount>

              <Include>

                $Request

              </Include>

            </Echo>

          </Value>

        </Message>

      </Process>

    </DoResponse>

  </default>

</select>

For-each  <For each="farmer" from="$LocalData.TempData" in="Find.Result.FarmerModel">
Select-by   
Schedule  

<Schedule after="PT5S" period="PT10S">

  <DoResponse target="ws:*">

    <Process>

      <Message type="text">

        <Value>

          grid_1

        </Value>

      </Message>

    </Process>

  </DoResponse>

</Schedule>