Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The FacetScript Language is one of the Atomic Domain Languages (ADLs).  It is a low level high performance scripting language natively executed by the TQLEngine A-Stack without any additional compilation besides initial parsing.

...

FacetScript language as well as other domain-specific languages used in Atomiton TQLEngine A-Stack stack is not bound to a specific syntax. Any syntax capable of expressing structure can be used to represent language constructs. Out of the box, both XML and JSON can be used.

...

How is FacetScript Implemented

The Atomiton TQLEngine FacetScript implementation within A-Stack is best understood if we understand the message processing flow within A-Stack.

Message Processing Flow

The Atomiton A-Stack architecture is a Scalable Event-Driven Architecture which uses a high performance NIO-based communication framework that provide low level asynchronous socket communications. Message processing flow steps are:

  1. A data structure called Facet Instance is associated with each incoming request. Each facet instance is identified by its facet ID and represents a capability to perform certain actions on the engine.
  2. Incoming requests without valid facet IDs are rejected. Each facet instance is also associated with its Facet Type which is a piece of executable code (a Java class) intended to actually process the request

...

  1. Once request legitimacy is established by successful resolution of its facet ID, a processing

...

  1. pipeline is created for low level request processing. This includes protocol handling, data decoding/encoding and initial data transformation and normalization.
  2. Once request data is presented in a universal fashion (as an instance of ListMap data structure), engine invokes appropriate facet type method using current connection context and facet instance information as arguments.

When to use FacetScript

Using FacetScript is optional and completely dependent on the developer role. For example, if you are a business analyst responsible for only writing simple TQL queries then using FacetScript is optional.

FacetScript Support in FacetTypes

FacetTypeFacetScript SupportedRequiredExamples
SffMsgFacetYesOptional

Note that SffMsgFacet does not expose any specific language constructs. FacetScript is the only option to use when using SffMsgFacet at that time of the package definition.

Code Block
languagexml
themeEclipse
titleFacetscript within TQL Query
linenumberstrue
 <NewFacetInstance fid="[:CONFIG.FsExecutorFid:]" name="Atomiton.FsExecutor" type="SffMsgFacet">
 <OnActivate>
 <ImportFacet>[:CONFIG.CommonMacroFid:]</ImportFacet>
 <!--============ MACROS ==============================================================-->
 <Include>[:Default.Location:]private/macros/fs/reset-fs.mc.xml</Include>
</OnActivate>
</NewFacetInstance>
SffTqlFacetYesOptional

Here we use FacetScript to loop through the Find Result and Update the VendorTitle value.

Code Block
languagexml
theme

From TQLEngine implementation perspective FacetScript can be used in following Facet Types.

...

Eclipse
titleFacetscript within TQL Query
linenumberstrue
<Query>
  <Find format="Version">
    <VendorInfo>
      <vendorSysId ne=""/>
    </VendorInfo>
  </Find>
  <For each="val" in="Find.Result.VendorInfo">
    <IF Condition="/'[:$LocalData.val.VendorTitle.Value:]' eq 'Sensor Provider'">
      <Log Message="Found Sensor Provider"/>
    </IF>
    <SetResponseData Key="val.VendorTitle.Value" Value="Actuator Provider"/>
  </For>
  <!-- Do an Update -->
  <Update From="Result">
    <Include>$Response.Message.Value.Find</Include>
  </Update>
</Query>
SffWdlFacetYes, when wrapped within Workflow Task's InvokeOptional
Code Block
languagexml
themeEclipse
titleFacetscript within Workflow Definition
linenumberstrue
<Workflow wid="[:CONFIG.WfExecutorWid:]" Limit="1" Live="1">
  <Task name="Executor" while="true">
    <Event name="Argument"/>
    <Invoke name="Execute" waitFor="Argument" fid="[%:Event.Argument.ExeFid:%]">
      <Include>[%:@WFRT:%]Event.Argument.Task</Include>
    </Invoke>
    <Invoke name="SetResult" fid="[:CONFIG.BehaviorFid:]">
      <FacetScript>
        <Process>
          <Message>
            <Value>
              <Set wid="[%:Event.Argument.Response.Wid:%]" target="[%:Event.Argument.Response.Result:%]">
                <Value>
                  <Include>[%:@WFRT:%]Invoke.Execute.Message.Value</Include>
                </Value>
              </Set>
              <Set wid="[%:Event.Argument.Response.Wid:%]" target="[%:Event.Argument.Response.Event:%]" value="true"/>
            </Value>
          </Message>
        </Process>
      </FacetScript>
    </Invoke>
  </Task>
</Workflow>

Mandatory within Package Definition

Using FacetScript is mandatory when defining a new package. New package definition contains the list of FacetTypes that the developer intends to deploy in A-Stack. Note that NewPackage itself is part of FacetScript.

Code Block
languagexml
themeEclipse
titleFacetscript in NewPackage Definition
<NewPackage>
<!-- ======================================================================= -->
    <NewFacetInstance fid="test" name="static" type="SffHttpStaticFileFacet">
        <OnActivate>
          <Process>
            <Resource>res</Resource>
          </Process>
        </OnActivate>
    </NewFacetInstance>
<!-- ======================================================================= -->    
    <NewFacetInstance fid="wstest" name="wstest" type="SffTcpFacet" context="keep">
        <OnOpen ModifyPipeline="WebSocketServerExtensionArgs"/>
        <OnRequest>
            <DoResponse target="wstest:*" process="wstest.$Request"/>
        </OnRequest>
    </NewFacetInstance>
<!-- ======================================================================= -->    
</NewPackage>