Thank you for being a valued client of CM First Group. If you have any technical issues or concerns, please open a ticket on support.cmfirstgroup.com, email CM First technical support at support@cmfirstgroup.com or call us on our 24/7 customer hotline at +1 (512) 623-7586.

Follow

Using the evolveIT Server from 3rd Party Applications

Overview

Information managed in an evolveIT Inventory is available for access by 3rd Party applications via simple messaging architecture and a straightforward data access API.

evolveIT provides a Service-Oriented Architecture. “Client” applications issue Service requests which are synchronously responded to by the evolveIT Server. There is no other mechanism available for accessing or managing evolveIT Inventory data. Client applications can be implemented in C# or C++ – however, this document is restricted to discussion of C# Clients.

Existing Services may be accessed from a 3rd Party Client by including the evolveIT “Client Foundation,” a collection of standard DLLs from the evolveIT Client. New Services may be provided by creating “plugin” DLLs (implemented in C++) and adding them to the Server\bin\Plugins directory of an existing Server. Subsequent Server sessions will then automatically make new Services defined in the new Plugins available to all client applications.

Client applications must login to the Server using the Login API, which is provided in the Client Foundation. They must also run a Status Monitor thread (again provided by the Client Foundation); “logout” is automatic when the Server detects termination of the “heartbeat” from this thread (there is no explicit “logout” API).

Information managed in evolveIT is accessed by “opening” an evolveIT “datasource,” an individual semantic model. Models exist for the “Inventory” itself – as reflected in the evolveIT Client Inventory Viewer – and for “top level” assets within the Inventory, including COBOL Programs and JCLs. This document is restricted to describing access to the Inventory model, it does not describe how to address or manipulate other models. The Client Foundation provides APIs for opening & closing datasources, and for querying the modelled information.

Services

All access to managed information in an Inventory is performed through evolveIT Services – a synchronous message exchange between client applications and the evolveIT Server.

Asynchronous information exchange may be achieved by executing server-side processing on a separate thread which makes Service calls back to the client, & creating a listener thread in the client to execute server-initiated Services. Asynchronous Services will not be described in this document.

Service are defined using simple textual definition language, and CM First provides a translation utility which transforms these definitions into C# and C++ Class definitions which can be compiled into a Server Plugin DLL and into a client application.

Definitions

A Service is defined thus

service service-name client sends input-data-structure server replies output-data-structure

service-name is the name by which the Service is identified

input- & output-data-structure are the names of Message definitions (which must be defined lexically prior to their use).

In C++ this generates a class named Mservice-name inheriting from AbstractMsg, in C# a class named service-name inheriting from bbIT.Messaging.BaseService

A Message definition takes the form

struct message-name {
       type field-name,
       …
}

message-name names the Message type. The message consists of zero or more comma separated field definitions.

In C# this generates a class named message-name, inheriting from bbIT.Messaging.BaseMessage; in C++ Mmessage-name inheriting from AbstractMessageAtom

type is the type of a field

  • int – signifies an integral numeric; it translates to the target language default integer type (int in C++ & C#)
  • text – signifies a text string of arbitrary length; it translates to the default string type of the target language (char* in C++, string in C#)
  • float – signifies a floating-point value; it translates to the default floating point type of the target language (float in both C++ & C#)
  • binary – signifies a binary value; in C++ this is of type BINARYDATA* (where BINARYDATA is the structure {DWORD length; BYTE* data;}, in C# this is of type byte[]
  • another-message-name – signifies a structured field with type given by the message name; in C++ this translates to a pointer (Manother-message-name*), in C# to a reference (another-message-name)
  • type[] – signifies an ordered collection of type; this translates to the C++ type List* (List is an internally defined wrapper for std::vector<void*>) or to the C# List<type>

A number of standard Message definitions are provided. These can be referenced at the start of a Service definition file thus

use basicatoms(m1, m2 …)

where the mi are common Message structure names. These are defined in a file basic.struct, supplied along with the Message Generator.

For a Service required to return no data use

use basicatoms(NoReply)

& specify

       server replies NoReply

The Message Generator (MsgGen.exe) must be called to generate the Message classes. The basicatoms definitions are already present on the Server in Server\bin\bbitcore.dll & are available in the Client Foundation in bbitMessaging.dll

MsgGen.exe -o output-dir -base service-group -- path\message-defs

service-group defines the name to be used for the generated code files.

C# source is placed in
               output-dir\C#\service-group.cs

C++ source is placed in
               output-dir\cpp\service-group.h
               output-dir\cpp\service-group.cpp

Initiating Service Execution from a Client (C#)

From a C# client execution of a Service follows a standard pattern

var svc = new bIT.Messaging.MessageDef.service(
bbIT.Messaging.bbITMessagingContext.serverConnection);

// initialise Input fields
svc.Input.field1 = …

svc.Execute();
if (!bbit.Shared.bbITMessagingRoutines.GetAndHandleMessageSuccess(svc, error-message)) {
       // process results from fields of svc.Output
       …
}

The GetAndHandleMessageSuccess routine returns true if the Service execution succeeded. If it failed it displays the error-message in a screen dialog and returns false when the dialog is dismissed. An alternative form of the call takes only the Service object as input and throws an exception if the Service execution failed, returning true otherwise.

The bbIT.Messaging.bbITMessagingContext.serverConnection object is created as a side-effect of login to the Server.

Client login

The login API must be called before any Services can be executed, it is provided in bbITShared.dll & is defined by

bool bbIT.Shared.bbITLogin.AttemptLogin(
       bbIT.Common.bbITServerInfo ifo,
       string u,
       string p,
       bool admin
)

where

   public class bbITServerInfo {
      public bbITServerInfo(string s, int p);
      public string displayName { get; }
      public string serverName { get; set; }
      public int serverPort { get; set; }
   }

u is the login user name, p is the user’s password (in plain text), admin must be false for 3rd party clients.

Once the client is logged in, it must initiate Status Monitoring thus (using bbITShared.dll) before attempting access the Inventory:

      var svc = new
      bbIT.Messaging.StartStatusMonitoring(
       bbIT.Messaging.bbITMessagingContext.serverConnection);

      svc.Execute();

 

      bbIT.Shared.bbITStatusMonitor.monitor.Start(svc.Output.port);

 

Executing a Service on the Server (C++)

For each Service to be provided, a Service implementation routine is required. This takes the standard form

int service-name(bbITServer* svc, AbstractMsg* msg) {
       Minput-type* in = static_cast<Minput-type*>(msg->GetInput());
       Moutput-type* out = static_cast<Moutput-type*>(msg->GetOutput());
       …
       // process in & generate out
       …
}

A return value of BBIT_OK indicates success, BBIT_ERROR indicates failure. An error message, if required, can be set using

void bbITServer::Error(int errNum, char* msg)

This routine is associated with the Service through a “Dispatch Table”. The Message Generator produces a SVCDEF[] object service-group_svcs defined in the service-group.cpp file, & places an extern definition of a SVCDESP[] object service-group_dsp in service-group.h. The Service implementer must execute a definition of service_group_dsp, typically in the form

SVCDESP service_group_dsp[] = {
       { “service-name1”, service-name1 },
       { “service-name2”, service-name2 },
       …
       { NULL, NULL }
}

Associating Service named “service-namei” with its implementation routine service-namei.

Server Plugin DLLs

Server Plugin DLLs, providing specialist Services for 3rd Party Clients must be placed in Server\bin\Plugins

Typically the base source for a Plugin includes a dll-name.h and dll-name.cpp file.

The following is a typical dll-name.h

#pragma once

 

#ifdef dll-name_EXPORTS

#define dll-name_API __declspec(dllexport)

#else

#define dll-name_API __declspec(dllimport)

#endif

 

The dll-name.cpp will need to #include (at least)

#include dll-name.h
#include “bbitserver.h”
#include “msgStructs.h”
#include “evservices.h”

plus for each service group

#include “service-groupi.h”

& must export a function

extern “C” {
       dll-name_API int Initdll-name-in-lowercase(BBITSERVER* svr) {
              …
              return 1;
       }
}

Within the Init function (note that the dll-name in the Init function name must be in lower case) all of the service-groupi_svcs and service-groupi_dsp objects must be registered, thus

svr->svr->registerServices(service-groupi_svcs, service-groupi_dsp)

When each login session starts, the Server searches the Server\bin\Plugins for DLL files, loads each one, and uses introspection to find the Initdll-name-in-lowercase routine. If one is found it is executed as part of the session startup – thus registering the DLL’s Services and making them available to be invoked.

Generated Service & Message Classes

C++ Messages

Specific Messages

For a Message named message (struct message { …}) the corresponding C++ class is

class Mmessage : public AbstractMsgAtom { … }

Constructors

Mmessage()

Construct a new Mmessage with default field initialisation.

Mmessage(Mmessage* data)

Construct a new Mmessage as a copy of a given Message (this is a deep copy, the storage for data can be released immediately after the construction)

Methods

For each single valued field field of type T (determined as described above)

T Getfield()

Returns the value of field

void Setfield(T data)

Set the value to a (deep) copy of data (storage for data can safely be released)

For each array field field of type T[]

T Getfield(int index)

Returns the value the index’th element of field

void Setfield(DWORD index, T data)

Sets the value of the index’th element of field to a (deep) copy of data

T Addfield()

Appends a new default constructed T to the end of field & returns it.

DWORD Lengthfield()

Returns the number of elements in field.

C++ Services

For a Service named service

class Mservice : public AbstractMsg { … }

Constructors

Mservice()

Constructs a new Mservice (input, output & status fields are all initialised using the default constructor)

AbstractMsgAtom* GetInput();

(inherited) Returns the input (“client sends”) message (to access the data to be processed)

AbstractMsgAtom* GetOutput();

(inherited) Returns the output (“server replies”) message (initially empty structure to be populated with return data)

MStatusMessage* GetStatus();

(inherited) Returns the Service status message.

Every Service contains an implicit StatusMessage field.

struct StatusMessage {
       int statuscode,
       text errMsg
}

void SetStatus(int num, char* statusmsg);

(inherited) Sets the statuscode of the Status message to a copy of statusmsg (statusmsg can safely be destroyed)

C# Messages

Specific Messages

For a Message named message (struct message { …}) the corresponding C# class is

class message : bbIT.Messaging.BaseMessage { … }

Constructors

message()

Construct a new message with default field initialisation.

Fields

For each single valued field field of type T (determined as described above)

T field { get; set; }

Gets or Sets the value of field

For each array field field of type T[]

bbIT.Common.bbITList<T> field( get; set; }

Gets or Sets the list corresponding to field.

namespace bbIT.Common {

   public class bbITList<T> : List<T> where T : new() {

      public bbITList();

 

      public T Add();

   }

}

 

(bbIT.Common.bbITList.Add() constructs a new T, appends it to the list & returns it)

C# Services

Fields

IbbITMessageStatus* status { get; }

(inherited) Returns the Service status message.

namespace bbIT.Messaging {

  public interface IbbITMessageStatus : IbbITBasicMessage {

    string message { get; }

    int errorCode { get; }

    bool success { get; }

  }

}

The actual status value is an instance of StatusMessage, which implements IbbITMessageStatus & adds set operations to the message, errorCode, & success fields

Methods

void Execute()

(inherited) Send the Service to the Server & awaits reply.

Accessing the Inventory – Client-side

Once a client application has connected to the evolveIT Server via the login API, it requires access to the Inventory. For this it must have a valid object instance which implements the bbIT.Common.IInventory interface

namespace bbIT.Common {

   public interface IInventory {

      Dictionary<string, object> ClientData { get; }

      string id { get; }

      string name { get; }

      string platform { get; }

 

      string this[string name] { get; }

 

      event EventHandler NameChanged;

 

      IList<string> AtrrNames();

      void CloseDatasource(IDatasource src);

      IDatasource GetDatasourceFor(string key, bool persist);

      IInventory GetToplevelInventory();

   }

}


The Client Foundation provides a standard implementation bbIT.Shared.bbITInventory, in bbITShared.dll.

Querying Installed Inventories

An evolveIT installation may support multiple Inventories. The preferred method for obtaining access to a specific Inventory is as follows (using bbITMessaging.dll & bbITShared.dll)

  1. Query the evolveIT Server to identify the installed Inventories.

var lstSvc = new
bbIT.Messaging.MessageDef.ListAllInventories(
     bbITMessagingContext.serverConnection);

      lstSvc.Input.recent = 0;

      lstSvc.Execute();

  1. Select the required element (of type Messaging.MessageDef.Entity) from lstSvc.Output.entities (using the bbIT.Messaging.MessageDef.Entity.name attribute)
  2. Use

public static bbIT.Shared.bbITInventory Create(bbIT.Messaging.MessageDef.Entity from)

To obtain the required IInventory.

Initialising an Inventory manually

If the Inventory name is known the alternative form

public static bbIT.Shared.bbITInventory Create(string invId, string invname,
                                                 string platformName)

Can be used. The form of the call is

var inv = bbIT.Shared.bbITInventory.Create(“name/-/-“, “name”, “IBM“)

Gaining access to the Inventory Viewer Model

To gain access to the Inventory, use the bbIT.Common.IInventory.GetDatasourceFor method

bbIT.Common.IDatasource ds = inv.GetDatasourceFor(“Inventory”, true)

(“Inventory” is the standard address for the Inventory Viewer model, value true prevents the model data from being purged from memory when this session is closed, allowing subsequent sessions, or parallel sessions, to open faster).

This creates an initialised IDatasource through which the Inventory model can be accessed.

New Service definitions must include an int type field identifying the Inventory. This field should be initialised with the bbIT.Common.IDatasource.id from the IDatasource object thus acquired.

Accessing the Inventory Model in a Service Implementation

If a Service requires to access the Inventory Viewer model, it must be supplied with the integer id of the opened data model (as described in the previous section). Using this value the Service obtains an access pointer for the database by calling

TbbITDatasource* bbITServer::GetDataSource(int id)

(Note that TbbITDatasource* pointers are internally managed & must never be destroyed by Service code)

Base Classes

The base classes for querying the Inventory Model are TbbITDatasourceFact and TbbITDatasourceSet, representing “facts” (items or relationship between items) and “sets” (semantic classifications) in the model.

TbbITDatasourceFact is sub-classed to TbbITDatasourceEntity & TbbITDatasourceRelation, providing an overlay of the model with ERA semantics.

The following classes are provided in the API

bbITStringTable

Is a wrapper for std::map<string, string>

bbITDatasourceFactVector

Is a wrapper class

class BBITCORE_API bbITDatasourceFactVector
       : public vector<shared_ptr<TDatasourceFact>> {

};

 

FactResult

The FactResult class is a wrapper class

class BBITCORE_API FactResult : public list<std::shared_ptr<TDatasourceFact>> {

public:

   virtual ~FactResult();

};

 

TDatasourceSet

Represents a Set defined in the IV model

Methods

string GetSetName();

Returns the name of the Set

TbbITDatasource* GetParent();

Returns a pointer to the TbbITDatasource within which the Set is defined.

FactResult GetMembers(bool brief = true);

Returns a list of pointers to TDatasourceFact object representing the Facts with are members of the Set

brief : true instructs that returned TDatasourceFact object do not include attribute information other than the Fact name (if a naming relationship is defined)

bool ContainsFact(std::shared_ptr<TDatasourceFact> fact);

Returns true if the supplied TDatasourceFact represents a member of the Set & false otherwise.

TDatasourceFact

Represents a Fact (member of a Set)

Methods

int GetType();

Returns

  • DATASOURCE_ENTITY if the object is a TDatasourceEntity
  • DATASOURCE_RELATION if the object is a TDatasourceRelation
  • DATASOURCE_UNKNOWN otherwise

 

TDatasourceFact(std::shared_ptr<TDatasourceFact> f);

Create a TDatasourceFact as a copy of a known instance

 

TDatasourceEntity

Represents a Simple Fact

Methods

std::shared_ptr<MEntity> GetEntity();

Returns an MEntity[i] which can be used to pass the Fact details to a client as a Message or field of a Message

char* GetName();

Returns the name of the Fact if it exists (if a naming relation is defined for the Fact’s Set, & this Fact is a Source for that Relation), or else nullptr

void GetAttrNames(bbITStringTable& attrs);

Populates attrs with the names of known Attributes (derived from targets of the has_attr relation) of the Fact

char* GetAttr(char* attrname);

Returns the value of the attribute if it exists, or else nullptr                           

Constructors

TDatasourceEntity(std::shared_ptr<TDatasourceEntity> f);

Create a TDatasourceEntity as a copy of a known instance

TDatasourceRelation

Represents a Relationship (complex Fact)

Methods

std::shared_ptr<TDatasourceFact> GetSource();

Returns the source TDatasourceFact                   

std::shared_ptr<TDatasourceFact> GetTarget();

Returns the target TDatasourceFact                   

std::shared_ptr<MRelationEntity> GetNttRelation();

Returns an MRelationEntity [ii] which can be used to pass the Fact details to a client as a Message or field of a Message

std::shared_ptr<MRelationText> GetTextRelation();

Returns an MRelationText [iii] which can be used to pass the Fact details to a client as a Message or field of a Message. The string values returned are the values of the Fact Targets (as opposed to the MEntity structures)

 

Constructors

TDatasourceRelation(std::shared_ptr<TDatasourceRelation> f);

Create a TDatasourceRelation as a copy of a known instance

TbbITDatasource

Represents an evolveIT model

Methods

Note: in all cases the brief parameter determines whether or not Attributes are included (as above)

FactResult FindFactsIn(std::shared_ptr<TDatasourceSet> set, bool brief = true);

 

Returns the list of Facts (In indeterminate order) which are members of set.

FactResult FindFactsWithName(
       std::shared_ptr<TDatasourceSet> inSet, char* name, bool brief = true);

 

Returns the list of Facts (In indeterminate order) which are members of set and have the given name.  

std::shared_ptr<TDatasourceFact> FindFactWithName(
       std::shared_ptr<TDatasourceSet> inSet, char* name, bool brief = true);

 

Equivalent to extracting the element at index 0 from the result of FindFactsWithName() on the same arguments, or nullptr if the list is empty.

FactResult FindFactsWithAttr(
       std::shared_ptr<TDatasourceSet> inSet, char* attrs, char* val, bool brief = true);

 

Returns the list of Facts (In indeterminate order) which are members of set and have value val for the Attribute attrs.   

                                  

std::shared_ptr<TDatasourceFact> FindFactWithAttr(
       std::shared_ptr<TDatasourceSet> inSet, char* attrs, char* val, bool brief = true);

 

Equivalent to extracting the element at index 0 from the result of FindFactsWithAttr() on the same arguments, or nullptr if the list is empty.

 FactResult FindFactsWithAttrs(
       std::shared_ptr<TDatasourceSet> inSet, char** attrs, char** val,
       bool brief = true);

 

Returns the list of Facts (In indeterminate order) which are members of set and for which each Attribute attrs[i] has the corresponding value val[i].

std::shared_ptr<TDatasourceFact> FindFactWithAttrs(
       std::shared_ptr<TDatasourceSet> inSet, char** attrs, char** val,
       bool brief = true);

 

Equivalent to extracting the element at index 0 from the result of FindFactsWithAttrs() on the same arguments, or nullptr if the list is empty.

FactResult FindRelatedFacts(
       std::shared_ptr<TDatasourceSet> relSet, std::shared_ptr<TDatasourceFact> srcFact,
       int dirn, std::shared_ptr<TDatasourceSet> inSet = nullptr, bool brief = true);

 

Returns all of the Facts which are Targets (if dirn has the value SRC2TGT) or Sources (if dirn has the value TGT2SRC) of relationships which are members of relSet in which srcFact is the Source (resp Target).

If inSet is not nullptr then only Facts which are members of inSet are returned

std::shared_ptr<TDatasourceFact> FindRelatedFact(
       std::shared_ptr<TDatasourceSet> relSet, std::shared_ptr<TDatasourceFact> srcFact,
       int dirn, std::shared_ptr<TDatasourceSet> inSet = nullptr, bool brief = true);

 

Equivalent to extracting the element at index 0 from the result of FindRelatedFacts() on the same arguments, or nullptr if the list is empty.

 set<string> FindRelatedTexts(
       std::shared_ptr<TDatasourceSet> relSet, std::shared_ptr<TDatasourceFact> srcFact,
       int dirn, std::shared_ptr<TDatasourceSet> inSet = nullptr, bool brief = true);

 

Returns the values of all of the Facts which are Targets (if dirn has the value SRC2TGT) or Sources (if dirn has the value TGT2SRC) of relationships which are members of relSet in which srcFact is the Source (resp Target).

If inSet is not nullptr then only Facts which are members of inSet are returned                                             (recall that static or inferred subsets of text may be defined)

boost::optional<string> FindRelatedText(
       std::shared_ptr<TDatasourceSet> relSet, std::shared_ptr<TDatasourceFact> srcFact,
       int dirn, std::shared_ptr<TDatasourceSet> inSet = nullptr, bool brief = true);

 

Equivalent to extracting the element at index 0 from the result of FindRelatedTexts() on the same arguments, or an unbound optional if the list is empty.

std::shared_ptr<TDatasourceFact> FindFactIn(
       std::shared_ptr<TDatasourceSet> set, bool brief = true);

 

Returns a single Fact (which one is not specified) which is a member of set, or nullptr if set is empty

std::shared_ptr<TDatasourceFact> FindFactById(FactReference* id, bool brief = true);

 

Returns a TDatasourceFact (actually a TDatasourceEntity) representing a Fact whose value is known – for example by virtue of being identified in a received Message.

Given the (char*) internal identity of a Fact, fact, the following archetypal code obtains the corresponding TDatasourceEntity (or nullptr, if there is no Fact with this identity) in TbbITDatasource src.

FACTID id = {FACTID_STRING, fact};

FactReference fref(src, &id);

shared_ptr<TDatasourceEntity> srcEnt = static_pointer_cast<TDatasourceEntity>(src->FindFactById(&fref));

 

FactResult FindRelationsEx(
       std::shared_ptr<TDatasourceSet> inSet,
       std::shared_ptr<TDatasourceSet> srcIn = nullptr,
       std::shared_ptr<TDatasourceFact> srcIs = nullptr,
       std::shared_ptr<TDatasourceSet> tgtIn = nullptr,
       std::shared_ptr<TDatasourceFact> tgtIs = nullptr);

 

Returns a list (in indeterminate order) of relationship Facts which are members of inSet.

  • If srcIs is non-null then it will be the Source of all returned Facts
  • If srcIn is non-null then the Source of every returned Fact is a member of srcIn
  • If tgtIs is non-null then it will be the Target of all returned Facts
  • If tgtIn is non-null then the Target of every returned Fact is a member of tgtIn

std::shared_ptr<TDatasourceRelation> FindRelationByEnds(
       std::shared_ptr<TDatasourceSet> setName,
       std::shared_ptr<TDatasourceFact> src,
       std::shared_ptr<TDatasourceFact> tgt);

 

If there is a relationship in setName which has src as its Source & tgt as its Target, then the returned TDatasourceFact (actually a TDatasourceRelation) represents that relationship, otherwise returns nullptr.

int NumRelations(FactResult& from, std::shared_ptr<TDatasourceSet> set, int dirn);

 

Returns the total number of relationship facts which are members of set and which have an element of from as their Source (dirn is SRC2TGT) or Target (dirn is TGT2SRC)

std::shared_ptr<TDatasourceSet> FindSetByName(char* name);

 

Returns a TDatasourceSet representing the set named name, or nullptr if no such set exists.

boost::optional<string> GetAttrValue(
       std::shared_ptr<TDatasourceFact> nttId, char* attrname);

 

Returns the string value of Attribute attrname from nttId, or an unbound optional if nttID does not have that Attribute.

bool FactIsInSet(
       std::shared_ptr<TDatasourceFact> fact, std::shared_ptr<TDatasourceSet> set);

 

Returns true if fact represent a member of set & false otherwise

 

An Example

As an example, the following outlines the necessary code to create a new service which takes as input

  • The name of a model type (set)
  • A list of element names
  • A list of relationship types
  • A list of target types

Used to obtain the collection of all elements which are members of at least one target type & are related to at least one member of the model type which has one of the given names.

For example: “Find all the Files and Database Tables written by the Programs P1, P2 & P3” would have

  • “ApplicationProgram” as the model type
  • { P1, P2 & P3 } as the list of element names
  • { “dataflow” } as the list of relation types
  • { “File”, “Table” } as the list of target types

Services

The following Service definition would be suitable

use basicatoms(ListEntitiesOutput)

 

struct FindRelatedSpec {

       int netId,

       text set,

       text[] names,

       text[] relations,

       text[] tgtSets,

}

 

service FindRelatedSvc client sends FindRelatedSpec server replies ListEntitiesOutput

 

This would be submitted to MsgGen.exe, as described, to generate C++ & C# classes to include in the project code.

Server Code

The following C++ code could be used to implement the Service:

int FindRelatedSvc(bbITServer* svr, AbstractMsg* msg) {

 

       MFindRelatedSpec* in = static_cast<MFindRelatedSpec*>(msg->GetInput());

       MListEntitiesOutput* out = static_cast<MListEntitiesOutput*>(msg->GetOutput());

       TbbITDatasource* src = static_cast<TbbITDatasource*>(

svr->GetDataSource(in->GetnetId()));

      

       FactResult foundntts;

       // find the source set

       auto srcSet = src->FindSetByName(in->Getset());

       if (srcSet != nullptr) {

              int jmax = in->Lengthids();

             vector<shared_ptr<TDatasourceEntity>> subjects;

              for (int j = 0; j < jmax; j++) {

                     auto srcEnt = dynamic_pointer_cast<TDatasourceEntity>(

src->FindFactWithName(in->Getnames(j)));

                     if (srcEnt != nullptr && src->FactIsInSet(srcEnt, srcSet)) {

                            subjects.push_back(srcEnt);

                     }

              }

              // the relations

              int rmax = in->Lengthrelations();

              vector<shared_ptr<TDatasourceSet>> relations;

              for (int r = 0 ; r < rmax ; ++r) {

                     auto relSet = src->FindSetByName(in->Getrelations(r));

                     if (relSet != nullptr) {

                            relations.push_back(relSet);

                     }

              }

              // & the target sets

              int lmax = in->LengthtgtSets();

              vector<shared_ptr<TDatasourceSet>> targets;

              for (int l = 0 ; l < lmax ; ++l) {

                     auto tgtSet = src->FindSetByName(in->GettgtSets(l));

                     if (tgtSet != nullptr) {

                            targets.push_back(tgtSet);

                     }

              }

              int rmax = in->Lengthrelations();

              for (auto& qset : relations) {

                     for (auto& subj : subject) {

                            for (auto& tgt : targets) {

                                   FactResult& tmp =

src->FindRelatedFacts(

qset, subj, SRC2TGT, tgt);

                                   foundntts.insert(foundntts.end(),

tmp.begin(), tmp.end());

                            }

                     }

              }

       }

       for (auto& ntt : foundntts) {

              auto rntt = dynamic_pointer_cast<TbbITDatasourceEntity>(ntt);

              if (rntt != nullptr) {

                     out->Addentities(rntt->GetEntity());

              }

       }

       return BBIT_OK;

}

 

Then, if the service group is X

SVCDESP X_dsp[] = {

       …

       { “FindRelatedSvc”, FindRelatedSvc },

       …

}

 

Compile (with other Services as required) into a Plugin DLL, as discussed above, which is placed into Server\bin\Plugins in the evolveIT Server installation.

Client Code

On the Client, the service can be invoked:

var svc = new bIT.Messaging.MessageDef.FindRelatedSvc (
bbIT.Messaging.bbITMessagingContext.serverConnection);
// initialise Input fields
svc.Input.netId = <int id of the Inventory>;

svc.Input.set = “ApplicationProgram”;

svc.Input.names = new List<string>() { P1, P2, P3 };

svc.Input.relations = new List<string>() { “dataflow” };

svc.Input.tgtSets = new List<string>() { “File”, “Table” };

svc.Execute();
if (!bbit.Shared.bbITMessagingRoutines.GetAndHandleMessageSuccess(svc, error-message)) {
       svc.Output.entities.ForEach(ntt => {
              …

});
}

 

 

 

[i] MEntity is the C++ realisation of a standard structure which can be used in Service definitions via

use basicatoms(Entity)

It is defined by

struct Entity {

       text id,

       int nid,

       int idIsInt,

       text name,

       text set,

       text datasource,

       Attribute[] attrs

}

There is a corresponding bbIT.Messaging.MsgDefs.Entity class available in C# to retrieve the data

[ii] MRelationEntity is the C++ realisation of a standard structure which can be used in Service definitions via

use basicatoms(RelationEntity)

It is defined by

struct RelationEntity {

       text id,

       text set,

       Entity source,

       Entity target

       text datasource

}

There is a corresponding bbIT.Messaging.MsgDefs.RelationEntity class available in C# to retrieve the data

[iii] MRelationText is the C++ realisation of a standard structure which can be used in Service definitions via

use basicatoms(RelationText)

It is defined by

struct RelationText {

       int id,

       text set,

       text source,

       text target,

text localId

}

There is a corresponding bbIT.Messaging.MsgDefs.RelationText class available in C# to retrieve the data

 

Models For EvolveIT

 eIT_model_1.PNG

 

Mapping Table for Program

 

Displayname

Name

IMS Segment

imssegment

CICS Queue

cicsqueue

Table

table

Physical Dataset

physicaldataset

External File

extfile

Physical File

file

PARM Card

parmcard

Nested Subprogram

subprogram

Application Program

applicationprogram

PSB

psbgen

TP PCB

tppcb

Database PCB

dbpcb

IMS Segment (access)

segmentaccess

Transaction

transaction

Dynamic Calls

variablecalls

Dynamic File Access

variablereadwrite

Program Entrypoint

entrypoint

Inaccessible Paragraph

deadparagraph

Copybook

copybook

System Program

systemprogram

Calls Program

program_calls_program

Dataflow Write

dataflow

Uses External File

program_extfile

Copies

program_copybook

External Dataflow Write

extdataflow

Has Entrypoint

program_entrypoint

Contains Inaccessible Para

program_deadpara

Calls Entrypoint

program_calls_entrypoint

Uncategorized Dataflow

uncategorized_dataflow

Program Nests

program_nests

Makes IMS Segment Access

MakesSegmentAccess

Has IMS Config

HasIMSConfig

Accesses IMS via PCB

UsesPCB

Dataflow Read

dataflow

External File reference

file_extfile

External Dataflow Read

extdataflow

Starts Transaction

program_starts_transaction

Returns To Transaction

program_returnsto_transaction

Cancels Transaction

program_cancels_transaction

Calls Via Variable

program_calls_via_variable

File Access Via Variable

ProgramReadWriteViaVariable

Defines PCB

DefinesPCB

Variable Is Program

variable_can_be_program

Runs Program

transaction_runs_program

PARM runs Program

parmrunsprogram

 

 eIT_model_2.PNG

 

Mapping Table for Class

 

Displayname

Name

Class

class

Interface

interface

Web Service

webservice

Web Method

webmethod

External Subsystem

extsubsystem

Method

method

Field

variable

CICS Pipeline

cicspipeline

Package

extpackage

Unknown Type

unresolvedtype

Inherits From

InheritsFrom

Implemented By

webserviceimpl

Type has Method

typehasmethod

Type has Field

typeexposesvariable

Inner Type

typedefinestype

Served By

webserviceserver

Has Web Method

WebServiceHasMethod

Implemented By Method

WebMethodImpl

Subsystem Contains

subsyscontainstype

Calls Method

methodcallsmethod

Package Contains

packagehastype

 

 eIT_model_3.PNG

 

Mapping Table for Database

 

Displayname

Name

Database

database

Schema

subdb

Column

column

Table

table

IMS Segment

imssegment

Physical Dataset

physicaldataset

Physical File

file

Application Program

applicationprogram

References Database

program_database

References Logical Database

program_subdb

Dataflow Write

dataflow

Contains Subdb

database_subdb

Is Referenced By

program_database

Dataflow Read

dataflow

Uncategorized Dataflow

program_table_uncategorized

Contains Dataset

database_collection

Contains Segment

databasecontainssegment

Contains Dataset

subdb_collection

Contains column

table_column

Is/Contains GDS

datasetisfile

Contains Table

database_collection

Job References Table

jcl_table

 

 eIT_model_4.PNG

 

Mapping Table for Batch Job

 

Displayname

Name

Batch Job

jcl

Job Step

step

Table

table

Job Procedure

jclproc

External File

extfile

Physical File

file

PARM Card

parmcard

Application Program

applicationprogram

System Program

systemprogram

Calls Program

jcl_program

Dataflow Read

dataflow

External Dataflow Read

extdataflow

Calls Job

jcl_jcl

Dataflow Write

dataflow

External Dataflow Write

extdataflow

Uncategorized Dataflow

uncategorized_dataflow

References File

jcl_file

Step reads File

stepreadsdatastore

Step writes File

stepwritesdatastore

Step executes Program

step_program

Job References Table

jcl_table

Calls Job Procedure

jcl_jclproc

Job References PARM

jobreferencesparm

Includes Job Step

jcl_step

Calls Program

jclproc_program

Calls Job Proc

jclproc_jclproc

Job Procedure References File

jcl_file

Includes Job Step

jclproc_step

 

 eIT_model_5.PNG

 

Mapping Table for Other Assets

 

Displayname

Name

Other Assets

txtasset

Physical File

file

External File

extfile

Screen

screen

Column

column

Batch Job

jcl

Job Step

step

Table

table

IMS Segment (access)

segmentaccess

Physical Dataset

physicaldataset

Job Procedure

jclproc

Transaction

transaction

CICS Queue

cicsqueue

IMS Segment

imssegment

Database

database

Schema

subdb

Column

column

Job Step

step

Application Program

applicationprogram

Nested Subprogram

subprogram

Dataflow Write

dataflow

Calls Program

program_calls_program

External Dataflow Write

extdataflow

Dataflow Read

dataflow

External Dataflow Read

extdataflow

Calls Program

jcl_program

Step executes Program

step_program

Starts Transaction

program_starts_transaction

Returns To Transaction

program_returnsto_transaction

Makes IMS Segment Access

MakesSegmentAccess

Calls Program

jclproc_program

Runs Program

transaction_runs_program

References Database

program_database

References Logical Database

program_subdb

Sends Screen

program_sendsscreen

Receives Screen

program_receivesscreen

 

 eIT_model_6.PNG

 

Mapping Table for Screen

                

Displayname

Name

MapSet

screenset

Screen

screen

Application Program

applicationprogram

Nested Subprogram

subprogram

Other Assets

txtasset

Uses Map

@ProgramUsesMap

Sends Screen

program_sendsscreen

Receives Screen

program_receivesscreen

MapSet Has Screen

screenset_screen

 

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

Powered by Zendesk