SDK Example Projects

This documentation page references Altium Vault, which has been discontinued. All your PCB design, data management and collaboration needs can now be delivered by Altium Designer and a connected Altium 365 Workspace.

 

Parent page: Altium Vault SDK

This document covers two SDK example projects - more details and information will be added in the future.

The Altium Vault SDK is installed with a number of C# example projects that have been developed to demonstrate important capabilities that are offered through the Vault Web Services. The projects provide valuable information on the structure, methods and resources used to develop web services applications and interfaces using C#.

The installation currently includes the following example projects:

  • BatchAddingParameters - batch addition of parameters to selected Vault components.
  • EventListener - define event notification Channels, Listeners and email alerts. Read more detail.
  • LoginAndListFolders - login and manipulate Vault folders.
  • PartChoices - view component Part Choices information.
  • RawSearch - perform a search for items within a Vault.
  • ReleaseComponent - release Items (including a Bridge-Item) and Item Revisions in folders, and change Lifecycle states. Read more detail.
  • UserManagement - add, update, and remove User Roles and their constituent Users.

Two of the key examples are covered in detail in the following sections.

Building (compiling) an example project creates its Windows executable file in the example's ..\bin\debug directory. The executable requires access to the DXP Server library (DxpServerSDK.dll), so if you copy the application (exe) to another location it will need to be accompanied by a copy of the server DLL.

Release Component example

The ReleaseComponent example is a good place to start for examining how C# applications can be developed for interacting with the Vault API. Load this project into Visual Studio from the \Altium Vault\SDK \examples\ReleaseComponent folder.

You may need to open Visual Studio with elevated privileges to guarantee a successful build. For Windows 7 or later operating systems, run Visual Studio as an administrator by right clicking on its entry (in the Start menu or programs listing) and selecting Run as Administrator. To always launch Visual Studio as an administrator, create a shortcut, open its properties (accessed by right clicking) and check the Run this program as an administrator check box under the Compatibility tab.

The ReleaseComponent example, as you would expect, releases a component into the Vault in line with the required revision and lifecycle structure. The design component entails PCB footprint and Schematic symbol files which are linked to constitute a basic Altium Designer component. The source Footprint and Symbol library files can be found in the project’s ..\TestFile folder.

A unique aspect of the example is that it also instigates and loads the non-standard Vault Item; a bridge-item - in this example, a simple web link to a video file. As Altium Designer creates and manipulates a defined range of Vault Items that pertain to electronics design (Components, Schematic sheets, etc) a bridge-item is not directly applicable on the design side of the Vault. However, such an Item will have significance to an external enterprise system, such as a company PLM or other system, and can be linked to relevant conventional Items in the Vault - it acts as a ‘bridge’.

Another process demonstrated by the example project is changing the Lifecycle state of a Revision in response to an external event. In this case, the event is manually instigated via the application's right-click menu option.

Note that most operations that can happen in the vault (creating Items Revisions, changing lifecycle states, etc) are framed in the context of an Item's Revision Definition and Lifecycle Scheme. To advance or regress a Revision's lifecycle state for example, its current lifecycle state needs to be referenced against a list of permitted changes (transitions) that are read in from the Vault. The permitted lifecycle transitions are based on the Revision's current lifecycle state and the Item's Lifecycle Scheme.

By way of example, if an Item Revision's current Lifecycle state is New From Design and its Item Lifecycle Scheme is set to Component Lifecycle, the permitted lifecycle transitions will be Promote To Prototype Use, or Abandon Component.

The program

In the ReleaseComponent example project, the actual process of releasing and updating components is instigated by the Release button in the Release dialog. Three dialogs (forms) are used; the Login dialog (FormLogin), the Explorer dialog (Explorer), and the Release dialog (FormRelease).

Login

Starting with the FormLogin class method, in response to the Login button, an IDSClient instance is created and assigned to the vault URI extracted from the Login form text box (textBoxIDSServer). The IDSClient.Login function then logs in to the IDS (Identity) service using the name/password text from the form, which returns loginResult (of the IDSLoginResult object type) holding user and session ID parameters.

IDSClient idsClient = new IDSClient(textBoxIDSServer.Text);
IDSLoginResult loginResult = idsClient.Login(textBoxUName.Text, textBoxPwd.Text, false)

Following a successful IDS login, the vaultUrl variable is constructed by replacing ids with vault in the form's URI string (textBoxIDSServer). A VaultClient instance is created and assigned to the variable's new URI.

string vaultUrl = textBoxIDSServer.Text.ToLower().Replace("ids", "vault");
VaultClient vaultClient = new VaultClient(vaultUrl);

The vaultClient object then logs in to the Vault service (vaultClient.Login) using the SessionID parameter (a GUID) from the established loginResult variable. The Explorer form is opened, passing the URI-specific vaultClient object variable.

vaultClient.Login(loginResult.SessionId);
Explorer explorer = new Explorer(vaultClient);

Explorer

Following a successful Login process, the Explorer dialog is populated with a list of the Folders and Items returned from the Vault, using the VaultClient.GetFolders and VaultClient.GetItems methods (Altium.Sdk.DxpAppServer.VaultClient). The returned folders list (a VaultFolderList object) is processed by parent/sub folder GUID and tree node to populate the Explorer tree panel (treeViewFolder).

VaultFolderList folders = vaultClient.GetFolders(String.Format("PARENTFOLDERGUID = '{0}' order by CREATEDAT", parentFolderGuid));

Similarly, the vaultClient class is subsequently applied to extract the Vault Items and Item Revisions (the GetItems and GetRevisions functions), along with the Vault request option to include Child objects. The methods populate the appropriate panel in the Explorer form (treeViewItemAndRevision).

VaultItemList items = vaultClient.GetItems(String.Format("FOLDERGUID = '{0}' order by CREATEDAT", folderGuid), new VaultRequestOptions() {VaultRequestOption.IncludeAllChildObjects});

VaultItemRevisionList itemRevisions = vaultClient.GetItemRevisions(String.Format("ITEMGUID = '{0}' order by CREATEDAT", itemGuid), new VaultRequestOptions() {VaultRequestOption.IncludeAllChildObjects});

Item lifecycle states (as GUID numbers) are retrieved by the Vault GetLifeCycleState function, and may range from just two states for the simplest Lifecycle Definition scheme to multiple states for more complex definitions. These are processed and added to the appropriate Explorer dialog form panel (listViewRevisionInfo).

VaultLifeCycleState state = vaultClient.GetLifeCycleStateByGuid(revision.LifeCycleStateGUID);

Any links between Item Revisions (such as those between a Symbol and Footprint that define a component) are mapped using GetItemRevisionLinksCount from a vaultClient class instance. These exist in a child/parent arrangement, for example where a Component Item is the Parent of the Symbol and Footprint Items, which are in turn Children of the Component.

int childCount = vaultClient.GetItemRevisionLinksCount(String.Format("PARENTITEMREVISIONGUID = '{0}'", revision.GUID));
int parentCount = vaultClient.GetItemRevisionLinksCount(String.Format("CHILDITEMREVISIONGUID = '{0}'", revision.GUID));

The range of Vault data collection and processing actions are used to populate the Explorer dialog using a tree structure and list, enabled by System classes such as System.Windows.Forms.ListViewItem. The methods ultimately cause matching HTTP SOAP requests to be sent to the Vault, such as GetALU_Items, GetALU_ItemRevisions and so on.

Release dialog

The Release dialog, instigated by the Release button in the Explorer dialog, is where the main action happens. The Release dialog is pre-populated with Symbol, Footprint and Component entries, and when enabled by the Enable Video Content Type checkbox, a bridge-item as a video URL link. Entry name suffix numbers are randomly generated by the Reset button - and when the dialog form is loaded.

A critical aspect of this dialog is the Revision Naming Scheme and Lifecycle Definition drop-down lists (comboBoxRevisionNamingScheme and comboBoxLifeCycleDefinition). These must be populated with the available list options from the Vault where they are defined. The vaultClient class members used are:

  • GetRevisionNamingSchemes - list of possible schemes, with HRID (human readable) and GUID information
  • GetLifeCycleDefinitions  - list of possible definitions, with HRID and GUID information
VaultRevisionNamingSchemeList schemes = vaultClient.GetRevisionNamingSchemes("", new VaultRequestOptions() {VaultRequestOption.IncludeRevisionNameLevels});
 
VaultLifeCycleDefinitionList lifeCycles = vaultClient.GetLifeCycleDefinitions("", new VaultRequestOptions() {VaultRequestOption.IncludeRevisionNameLevels});

Note that Item types are normally predefined by the Vault, but the new bridge-item is defined in the example by a hard coded GUID.

Creating the Release Script

The populated and configured entries in the Release dialog are sent as Vault entries with the Release button action. The methods in the ReleaseComponent namespace (in FormRelease.cs) define and send the data as a single composite script to the Vault API. Here, the script not only has a significant number of direct HTTP requests (rather than SOAP requests), but also needs to include the actual data that will be hosted in the vault - namely, the Symbol and Footprint files in the example's ..\TestFile sub-folders.

To avoid an inefficient (read; slow) transfer response, the 'Release Component' script (componentReleaseScript) is compressed/zipped into a serialized 'execute' script as a binary file. Alerted by the incoming ExecuteScript format, the receiving Vault API unzips the data and processes the results.

Here, the buttonRelease_Click method creates the VaultScript object (Altium.Sdk.DxpAppServer.VaultScript) and instigates the 'Release Component' script command functions (Altium.Sdk.DxpAppServer.AtomicCommandGroup)

VaultScript componentReleaseScript = new VaultScript();
AtomicCommandGroup componentReleaseCommandGroup = componentReleaseScript.AddCommandGroup("Release Component");

Using the data extracted from the Release dialog, relevant data commands are sequentially added to the script. The Altium.Sdk.DxpAppServer assembly offers specific classes for the task, such as:

  • ScriptCommandAddFolder
  • ScriptCommandAddItem
  • VaultItemRevisionLinkList
  • VaultItemRevisionLink
  • ScriptCommandReleaseItemRevision  

Commands to create the Vault Folders and Items are then added to the script using the above AddFolder and AddItem script command methods. The next steps add commands to release Item Revisions (using ScriptCommandReleaseItemRevision), and include an assembled list of revision links (VaultItemRevisionLink). The implemented links define the component by linking it to its constituent Symbol and Footprint Items.

ScriptCommandReleaseItemRevision releaseSymbolCommand = componentReleaseCommandGroup.CreateCommandReleaseItemRevision();

Once complete (and the Video Item is assessed for inclusion), the Release Component script is processed and sent to Vault API using the HTTP POST method. This applies the ExecuteScript function from the VaultClient class instance.

Note that ExecuteScript harnesses the compression/streaming capabilities of the Ionic.Zip.Reduced class assembly, which must be included as a reference prior to building the example. Note also that if the built executable, ReleaseComponent.exe, is copied and run from its own folder it must have access to both the Ionic.Zip.Reduced.dll and System.Net.Http.dll libraries.
vaultClient.ExecuteScript(componentReleaseScript);

The returned response from the Vault then repopulates the Explorer dialog with the newly released vault Item Revisions.

Changing a Revision Lifecycle state

The lifecycle change option is available through a right-click context menu, after first selecting a Revision entry in the Explorer dialog.

The Revision Lifecycle states will only be available and editable if the released Items were configured for the higher order of Naming Schemes and Lifecycle Definitions. When releasing the example components select the (say) Component Revision Scheme and Component Lifecycle options from the dialog drop-down lists.

The initial action of selecting an Item Revision in the Explorer dialog retrieves its lifecycle state (and any links) from the Vault, then inserts HRID strings and lists the information in the lower panel area in the Explorer form.

VaultLifeCycleState state = vaultClient.GetLifeCycleStateByGuid( revision.LifeCycleStateGUID);
 
ListViewItem stateItem = new ListViewItem(String.Format("{0} is in the {1} state", revision.HRID, state.HRID));
listViewRevisionInfo.Items.Add(stateItem);

Subsequently right-clicking on the selected Item Revision retrieves the full list of lifecycle stages, states and possible transitions that apply to the Item's Lifecycle Definition.

VaultLifeCycleDefinition lifeCycleDefinition = vaultClient.GetLifeCycleDefinitionByGuid(item.LifeCycleDefinitionGUID,new VaultRequestOptions(){VaultRequestOption.IncludeAllChildObjects});

This effectively retrieves the information that is presented in Altium Designer's Edit Lifecycle Definitions dialog for that particular Lifecycle Definition. If an Item's Lifecycle Definition is set to 'Component Lifecycle' for example, the Altium Designer dialog would appear as below, where the information is presented visually in a tabular form:

Altium Designer's Edit Lifecycle Definitions dialog is a visual representation of the information retrieved by a GetLifeCycleDefinitions request.
Altium Designer's Edit Lifecycle Definitions dialog is a visual representation of the information retrieved by a GetLifeCycleDefinitions request.

In the ReleaseComponent project, the retrieved information includes 'lifecycle state before' and 'lifecycle state after' statements for each possible state transition (as GUID numbers). The currently selected Item Revision's lifecycle state (as a GUID) can then be compared to 'before' statement GUIDs in the retrieved list, therefore deriving a set of matches. The 'after' statements for each of these matches then populate the right-click context menu as their respective HRID (description) string.

Selecting an Item LifeCycle change in the ReleaseComponent example project.
Selecting an Item LifeCycle change in the ReleaseComponent example project.

Clicking on one of the options will instigate the VaultLifecycleChangeState function, thereby sending a formatted state transition request to the Vault for the selected Item Revision. See the Explorer's contextMenuItemRevision_Opening method section.

VaultLifeCycleStateChange stateChange = new VaultLifeCycleStateChange(itemRevision.GUID, stateTransition.GUID);
vaultClient.AddLifeCycleStateChange(stateChange);

The Item information is subsequently retrieved from the Vault again, repopulating the Vault with the updated data.

Note that the action of retrieving the list of Items in the Vault (vaultClient.GetItems) yields all relevant information, including historical data detailing changes that have occurred to the Item and its Revisions.

For example, the previous lifecycle changes are listed in the Vault's response as a sequential set of information blocks that hold the description, time, user and before/after states for each historical lifecycle transition. The historical information is not used in this example.

Event Listener example

The EventListener example project demonstrates the use of the Event Dispatch Service (EDS) hosted by the Vault server, and the Event Notifications it generates. When enabled, the EDS acts as an Event notification engine for the Vault service by monitoring activity and creating event messages for external distribution.



The EDS Event Notification messages are available through a nominated Event Channel, which can be subscribed by Listeners - those that are registered to receive event messages. Specific Event Notifications can be retrieved from the EDS by interrogating the service from an external application, as a Listener registered to the Event Channel, then filtering the response content accordingly.

A wide range of Vault activity (mainly changes and additions) is logged by the EDS and available as Event Notifications. These can be loosely grouped as:

  • Folder events
  • Item events
  • Revision events
  • Revision Naming Scheme events
  • Lifecycle Definition events

The Event Channel name is available as a Vault option setting in Altium Designer, but can also be defined and modified by an authorized external system. Listeners are nominated names that are registered (associated) with an Event Channel on a session basis, and are defined by the external listening application or service.

To demonstrate the EDS service and its interaction with the Vault service, the C# EventListener example project provides the base functionality needed to disseminate specific Event Notifications to a nominated Listener and email address.

As a sequence of function steps, the compiled EventListener executable allows you to:

  • Login to the Vault Server services
  • Set the Vault Event Channel
  • Register (or un-register) a Listener to Event Channel
  • Nominate an email address to receive event notification summaries
  • Start and stop the Event listening (monitoring) cycle

For the purposes of the demonstration example, only Item Release and Lifecycle change event notifications are processed for sending, and a Gmail SMPT Client is used for the email function.

The program

The EventListener C# project is essentially composed of two straightforward dialog screens defined by the FormLogin and FormListener forms and their associated objects and methods - these appear as the Login and Listener dialogs, respectively. As with all Vault SDK examples in the C# domain, the key resource is the DxpServerSDK class assembly and the member classes in its principle namespaces.

The most direct way to look at the program source here is probably as a sequence of operational steps, along with the C# objects they involve.

Starting with FormLogin section, the Login button method simply captures the dialog’s URI and name/password entries to an IDSClient.Login function, logs in to the IDS, then redirects the login URI to the Vault and logs in using the initial login Session ID. For more detail, see the above Release Component Login section.

A successful Vault login result calls the FormListener method (in FormListener.cs). Here, the Vault URI is reassigned to the EDS service and passed to a new instance of EDSClient. The FormListener form is loaded and its text boxes populated with the EDSClient URI and the current Vault's current Event Channel property - the latter is sourced from the Vault instance with the VaultInfo.EventChannel property of the vaultClient object.

this.textBoxEDSServer.Text = edsClient.ServiceURL.ToString();
this.textBoxChannelName.Text = vaultClient.VaultInfo.EventChannel;

Channel Name

A change in the entry of the Channel Name text box (such as typing in a new Name) instigates the ChannelName_TextChanged event handler. This performs dialog housekeeping actions such as enabling/disabling the appropriate text boxes and buttons.

Clicking the Set Channel button instigates the buttonSetChannel_Click method which, along with dialog configuration housekeeping, updates the Vault’s Event Channel name through an UpdateVaultInfo request to the Vault service.

vaultClient.VaultInfo.EventChannel = channelName;
vaultClient.UpdateVaultInfo(vaultClient.VaultInfo);

Listener Name

The Listener Name field, now enabled, accepts a typed name that will apply to the current session. A ListenerName_TextChanged event handler, as above, performs appropriate dialog housekeeping.

The action of registering a Listener Name to the assigned Event Channel occurs when the Register Listener check box is checked. Its associated checkBoxRegisterListener_CheckedChanged method, along with the usual dialog housekeeping, sends a register request to the EDS service using the RegisterEventListener member of the EDSClient object.

listenerName = textBoxListenerName.Text;
edsClient.RegisterEventListener(listenerName, new List<string>() {channelName});

Note that unchecking the Register Listener box will unregister an existing (currently active) Listener Name with the EDS service - EDSClient.UnRegisterEventListener.

With an email address entered in the Receive Email field, the event listening action is started with the Start/Stop Listening button, which instigates the buttonListen_Click method. This defines and configures the email sending service by creating an instance of the System.Net.Mail.SmtpClient class to use a Gmail™ server, and implements the credentials for a valid Gmail account.

smtpClient = new SmtpClient("smtp.gmail.com", 587);
        
smtpClient.Credentials = new NetworkCredential("eventlistenertest", "Altium123!");

Mail address strings are then created from the email address extracted from the dialog text box, and the StartListen method instigated.

Listening and processing

For the EventListener example, the action of listening for Event Notifications is formed by sending a stream of Read requests to the EDS service, then responding to any return messages that contain the appropriate content. In this case, that’s a notification of a Revision Release or a change in Lifecycle State.

The StartListen code instigates a new thread that creates a list of EDS messages (EDSQueueMessageList) by using ReadEvents calls to the service. The listening method is encapsulated in a While loop, which sustains until the thread is aborted by the StopListen method. A further loop decodes (deserializes) the JSON content message and processes the results.

Note that the body content of Event Notification responses is in the JSON (JavaScript Object Notation) format and needs to be deserialized as a JSON Object. See JSON encoded Events below.
This is handled through the Newtonsoft.Json class assembly - JsonConvert.DeserializeObject.
EDSQueueMessageList messages = edsClient.ReadEvents(10, listenerName, appGuid, appName, Environment.MachineName);

foreach (var message in messages)
{
dynamic contentJson = JsonConvert.DeserializeObject(message.Content);

Each returned event message is scanned for the targeted strings of ‘Release’ (for a Revision release event) and ‘RevisionStateChange’ (for a Lifecycle change event). When detected, the relevant GUID value is extracted from the message content (contentJson.Revision.GUID.Value for the Release event) and the Vault interrogated for the updated item information. The collected information is then assembled into a suitable email alert string.

Taking the example case of a Lifecycle change event being detected, the ItemRevison and LifeCycleSateAfter identifiers (as GUIDs) are stored and then applied in the Vault requests that follow. These data requests are targeted (though filtering) at the specific Revisions and Lifecycle Transitions in the Vault that triggered the Event Notification - as identified by the stored GUIDs.

VaultItemRevision revision = vaultClient.GetItemRevisionByGuid(revisionGuid, new VaultRequestOptions() { VaultRequestOption.IncludeAllChildObjects});
VaultLifeCycleState state = vaultClient.GetLifeCycleStateByGuid(lifeCycleStateGuid);

The resulting information held by the revision and state variables is applied to the SendEmail method to form the email message content.

SendEmail(String.Format("LifecycleState of {0} has been updated to {1} at {2}", revision.HRID, state.HRID, revision.LastModifiedAt));

The event message IDs (as GUIDs) are then added to the messageID list, which is sent to the EDS service as a standard SOAP-XML message (edsClient.ProcessEvents).

Backing up slightly, the SendEmail method simply sends an email containing the assembled content passed by the calling StartListen method.

mailMessage.Body = content;
smtpClient.Send(mailMessage);

As the content passed to the email function represents Event Notification information (event type, object name, time, etc) the resulting email presents a summary of the Event, thereby informing (or perhaps alerting) the email recipient of the change.

JSON encoded Events

As outlined above, event messages (notifications) from the EDS are formed in the JSON (JavaScript Object Notation) open standard, and decoded using the Newtonsoft.Json assembly. The basic syntax for JSON includes comma-separated objects as Name-Value pairs, array lists, and strings delimited by double-quotes. See JSON for more information.

The transmitted events from the EDS service have the following object stucture:

{"Action":"xxx","Item":{"ObjectFields"}}
- where xxx can be Add, Update, Delete, Release, RevisionStateChange.

In the EventListener example, the event actions of 'Release' and 'RevisionStateChange' are detected by interrogating the value of the Action field with contentJson.Action.Value.

By way of example, the structure for the JSON event of adding a Vault Item would be:

{
"Action":"Add",
"Item":
  {
  "GUID":"",
  "HRID":"",
  "CreatedAt":"",
  "LastModifiedAt":"",
  "CreatedByGUID":"",
  "LastModifiedByGUID":"",
  "CreatedByName":"",
  "LastModifiedByName":"",
  "SharingControl":0,
  "AccessRights":0,
  "Description":"",
  "FolderGUID":"",
  "LifeCycleDefinitionGUID":"",
  "RevisionNamingSchemeGUID":"",
  "ContentTypeGUID":"",
  "Revisions":[],
  "IsShared":0
  }
}

Note that the JSON event structure above does not include values for each Name-Value object. Note also that the Revisions item value is an array, indicated by the square brackets [].

For the process illustrated in the EventListener program, the (human readable) Item name would be returned by:

contentJson.Item.HRID.Value.

The returned JSON content for the range of possible events (Add, Update, Delete, Release, RevisionStateChange) is generally based on the properties for the Item that has changed or been created. In practice, the EDS JSON event content for an action like adding a Vault Item will be similar to that shown below.

The EDS event message when a Vault Item has been added.
The EDS event message when a Vault Item has been added.

A definitive way to ascertain what message will be returned for a particular event, and under what circumstances, is to create a test program that decodes and displays all events as they occur.

A quick change to achieve a basic reporting program is to simply insert a generic display command (with string conversion) in the EventListener example project, as shown below for the StartListen method in the FormListener code. See line 5, highlighted in gray.

foreach (var message in messages)
{
  dynamic contentJson = JsonConvert.DeserializeObject(message.Content);

  MessageBox.Show(contentJson.ToString());  //added to display all decoded JSON events
 

When making changes to the Vault content in Altium Designer, all resulting notifications from the EDS service will be decoded and displayed in full, so the EDS notification structure can be tested for a specific Vault action. The display function could also be wrapped in a conditional If statement to detect and then process a particular event Action of interest - as is done for the Release and RevisionStateChange actions in the EventListener code.

The images above and below are examples of this simple Event detection and content display approach.

The decoded JSON message generated by the EDS in response to the release of a Revision Item.The decoded JSON message generated by the EDS in response to the release of a Revision Item.

For an overview of the Altium Vault SDK and server-delivered Web Services, go to:

 

Content