SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document :...

87
SmartConnector Developers Guide Buildings Labs

Transcript of SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document :...

Page 1: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Buildings Labs

Page 2: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 1 of 86

1 Support.................................................................................................................................................. 5

2 Revision History .................................................................................................................................... 5

3 Overview ............................................................................................................................................... 6

3.1 Scope ............................................................................................................................................. 6

3.2 What is SmartConnector? ............................................................................................................. 6

3.2.1 Processor ............................................................................................................................... 7

3.2.2 Processor Configuration ........................................................................................................ 7

3.2.3 SmartConnector EWS Servers ............................................................................................... 7

3.2.4 REST Endpoints...................................................................................................................... 8

3.2.5 Endpoint Configuration ......................................................................................................... 8

3.2.6 SmartConnector Portal ......................................................................................................... 8

3.2.7 Worker Manager and Workers ............................................................................................. 8

3.2.8 Extension ............................................................................................................................... 8

3.2.9 Persistent Data Store ............................................................................................................ 8

3.2.10 In-Memory Cache .................................................................................................................. 9

3.2.11 Logging .................................................................................................................................. 9

3.2.12 Licensing ................................................................................................................................ 9

4 Common Data Flows ........................................................................................................................... 10

4.1 Retrieving Data from an EWS Server .......................................................................................... 10

4.1.1 EwsClient ............................................................................................................................. 10

4.1.2 AlarmItemReader ................................................................................................................ 10

4.1.3 ValueItemReader ................................................................................................................ 10

4.1.4 HistoryItemReader .............................................................................................................. 10

4.1.5 SubscriptionReader ............................................................................................................. 10

4.2 Providing Data to an EWS Client ................................................................................................. 10

4.2.1 Asynchronous Data Management ...................................................................................... 11

4.2.2 Synchronous Data Management ........................................................................................ 11

4.2.3 Hybrid Data Management ................................................................................................... 11

4.3 Providing Data to a Third Party ................................................................................................... 12

4.3.1 Active Third Party ................................................................................................................ 12

Page 3: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 2 of 86

4.3.2 Passive Third Party .............................................................................................................. 12

5 Develop an Extension .......................................................................................................................... 13

5.1 Problem Statement ..................................................................................................................... 13

5.2 The Design ................................................................................................................................... 13

5.2.1 SetupProcessor ................................................................................................................... 14

5.2.2 UpdateProcessor ................................................................................................................. 14

5.2.3 Custom EWS Server ............................................................................................................. 14

5.3 Configure NuGet Feed ................................................................................................................ 15

5.4 Creating Extension Assembly ...................................................................................................... 16

5.4.1 Create an Empty Solution ................................................................................................... 16

5.4.2 Add Class Library Project ..................................................................................................... 16

5.4.3 Annotate Your Extension Assembly .................................................................................... 17

5.5 Processor Development (Setup Processor) ................................................................................ 17

5.5.1 Add Processor Class ............................................................................................................ 17

5.5.2 Add NuGet Reference ......................................................................................................... 18

5.5.3 Writing Your Code ............................................................................................................... 20

5.6 Processor Development (UpdateProcessor) ............................................................................... 33

5.6.1 Configurable Properties ...................................................................................................... 34

5.6.2 Time to Refactor ................................................................................................................. 34

5.6.3 Execute_Subclass ................................................................................................................ 37

5.7 Custom EWS Server Development .............................................................................................. 45

5.7.1 Add ServiceHost Class ......................................................................................................... 45

5.7.2 Add DataExchange Class ..................................................................................................... 48

5.7.3 Add Custom Request Processor Class ................................................................................. 50

5.8 One Final Edit .............................................................................................................................. 51

6 Testing an Extension ........................................................................................................................... 52

6.1.1 Install a Test Runner............................................................................................................ 52

6.1.2 Install SmartConnector ....................................................................................................... 53

6.2 Create Unit Testing Project ......................................................................................................... 53

6.2.1 Add Reference to Extension Assembly ............................................................................... 54

6.2.2 Add Reference to SmartConnector ..................................................................................... 54

Page 4: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 3 of 86

6.2.3 Transpose Configuration Settings ....................................................................................... 55

6.2.4 Add NuGet Reference ......................................................................................................... 56

6.3 Add Test Fixture Class (SetupProcessor) ..................................................................................... 56

6.3.1 FixtureOneTimeSetup_Base ................................................................................................ 58

6.3.2 CreateTestableProcessor .................................................................................................... 58

6.3.3 ValidateTest ........................................................................................................................ 59

6.3.4 ExecuteTest ......................................................................................................................... 59

6.3.5 CancelTest ........................................................................................................................... 59

6.3.6 Debugging Your Tests .......................................................................................................... 60

6.4 Add Test Fixture Class (UpdateProcessor) .................................................................................. 60

7 Deploying Your Extension ................................................................................................................... 62

7.1 Deploy Binary Files ...................................................................................................................... 62

7.2 Add Configuration (SetupProcessor) .......................................................................................... 62

7.3 Add Configuration (UpdateProcessor) ........................................................................................ 64

7.4 Verify Custom Server .................................................................................................................. 67

8 Licensing Your Extension ..................................................................................................................... 70

8.1 Create SmartConnectorServer Entries ........................................................................................ 71

8.2 Update Extension Assembly ........................................................................................................ 74

8.3 Enable Licensing at the Processor ............................................................................................... 75

8.4 Updating Extension Assemblies .................................................................................................. 75

9 Appendix ............................................................................................................................................. 76

9.1 Strong-Named Assemblies .......................................................................................................... 76

9.2 NuGet Packages .......................................................................................................................... 76

9.3 SmartConnector Interfaces ......................................................................................................... 77

9.3.1 ITraversable ......................................................................................................................... 77

9.3.2 ILongRunningProcess .......................................................................................................... 77

9.3.3 IEndpoint ............................................................................................................................. 78

9.3.4 IStaThreadedProcessor ....................................................................................................... 78

9.4 SmartConnector Attributes ......................................................................................................... 78

9.4.1 CollectionLengthAttribute................................................................................................... 78

9.4.2 ConfigurationDefaultsAttribute .......................................................................................... 78

Page 5: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 4 of 86

9.4.3 ConfigurationIgnoreAttribute ............................................................................................. 78

9.4.4 EncryptedStringAttribute .................................................................................................... 78

9.4.5 NotTraverseableAttribute ................................................................................................... 78

9.4.6 RandomStringDefaultValueAttribute .................................................................................. 79

9.4.7 TooltipAttribute .................................................................................................................. 79

9.4.8 VisibleWhenAttribute ......................................................................................................... 79

9.5 EwsServerDataAdapter ............................................................................................................... 79

9.6 Custom Licensing ........................................................................................................................ 79

9.7 Sharing Data within SmartConnector ......................................................................................... 80

9.7.1 In-Memory Cache ................................................................................................................ 80

9.7.2 Processor Values ................................................................................................................. 81

9.8 Managed Clients ......................................................................................................................... 81

9.9 Coordinating Actions ................................................................................................................... 82

9.10 Logging ........................................................................................................................................ 83

9.11 Third Party Tools ......................................................................................................................... 84

9.11.1 SoapUI ................................................................................................................................. 84

9.11.2 Fiddler ................................................................................................................................. 85

9.12 Supported Operating Systems .................................................................................................... 85

9.13 Supported Database Servers ....................................................................................................... 85

Page 6: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 5 of 86

1 Support Schneider Electric provides branch and channel partners with planning and implementation assistance

from Buildings Labs. To request help, send an email to Product Support specifying the solution name and

the type of assistance you require. Product Support will relay your request to the appropriate support

team.

North America (NAM) Product Support

Building Management Systems (BMS): [email protected]

Global Product Support

Building Management Systems (BMS): [email protected]

Most questions can be answered by accessing the SmartConnector Developer Community page located

at https://exchangecommunity.schneider-electric.com/community/bms/struxureware/smartconnector-

developer.

2 Revision History

Date Author Revision Changes Made 10/21/2014 MRS 1 Initial release

02/16/2015 MRS 2 Updated for v1.3

09/30/2015 MRS 3 Updated for v2.0

04/11/2016 MRS 4 Updated for v2.1

12/22/2016 MRS 5 Updated for v2.2

12/15/2017 MRS 6 Updated for v2.3

© 2017 Schneider Electric. All Rights Reserved. Schneider Electric, StruxureWare, SmartStruxure solution, and EcoStruxure are trademarks owned by Schneider Electric Industries SAS or its affiliated companies. All other trademarks are the property of their respective owners.

Page 7: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 6 of 86

3 Overview

3.1 Scope

This document is intended as a guide for developers using SmartConnector – the Windows service

middleware framework developed by Schneider Electric Buildings Labs. This document assumes the

reader has the requisite knowledge of C# or VB.NET® and is moderately comfortable developing class

libraries in Visual Studio® .NET.

This document will not cover the details pertaining to installation, configuration, monitoring, and control

of SmartConnector in a runtime environment. That information can be found in SmartConnector

Installation and Configuration Guide. It is assumed that this document has been reviewed and the

topics contained within are fully understood before continuing.

3.2 What is SmartConnector?

When developing solutions, there is frequently a need for software that can bridge the gap between

Schneider Electric systems and third-party systems and data sources. This software goes by varying

names: protocol shims, glue logic, or more generally, middleware. As different projects are analyzed,

patterns begin to emerge where this middleware performs similar actions with only minor variations

from solution to solution. SmartConnector was conceived to be this middleware framework.

SmartConnector is an extensible and configurable application framework. At its simplest,

SmartConnector is a multi-threaded Windows service. Threads are configured to execute custom code

written by solution providers and integrators.

SmartConnector also provides the infrastructure to provision HTTP endpoints. These endpoints can

either serve data to Schneider Electric systems and third-party clients via Schneider Electric’s

EcoStruxure Web Services (EWS) SOAP protocol or generic RESTful services.

Figure 1 shows the general architecture of SmartConnector.

Page 8: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 7 of 86

Figure 1: SmartConnector General Architecture

3.2.1 Processor

A Processor is custom code that is designed to accomplish a task. While SmartConnector does include

some sample Processor classes for operational validation and demonstration purposes, Processors are

written by others using SmartConnector’s public libraries. These libraries are packaged into a

SmartConnector Extension.

The scope of a Processor can vary from simple to very complicated. Often, several Processors are

required to function cooperatively to accomplish the necessary tasks for a solution.

3.2.2 Processor Configuration

While a Processor defines how work is accomplished, a Processor Configuration specifically dictates

what gets accomplished. A Processor Configuration contains all of the information needed to instantiate

a class at runtime, hydrate all properties of that class, and validate that everything is correct before

finally executing the Processor. A Processor Configuration also links to the requisite scheduling

information which determines when and how often SmartConnector will run a Processor.

3.2.3 SmartConnector EWS Servers

SmartConnector provides the infrastructure to serve data to any EWS Client via native SmartConnector

EWS Servers. Multiple EWS Servers can be provisioned, each with its own data isolated from the others.

This data can be static data stored in SmartConnector’s database or data dynamically obtained from a

Page 9: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 8 of 86

third party via a custom EWS Server. As with Processors, custom EWS Servers are written by third

parties and packaged into a SmartConnector Extension.

3.2.4 REST Endpoints

While EWS is useful for passing data to and from those Schneider Electric systems which support it, third

parties interested in that same data do not know how to “speak EWS”. To remedy this, SmartConnector

includes a configurable RestProvider infrastructure. An EwsRestProvider class is configured with an

Endpoint Configuration to serve data from either a native SmartConnector EWS Server, one based on

the EWS SOAP protocol, and one based on the SmartStruxure Building Operation (SBO) native CSP

protocol. Custom RestProviders can also be written by third parties and packaged into a

SmartConnector Extension.

3.2.5 Endpoint Configuration

In the same way a Processor Configuration defines how a Processor runs; an Endpoint Configuration

defines how a REST Endpoint will be provisioned. An Endpoint Configuration contains all of the

information needed to instantiate a class at runtime, hydrate all properties of that class, and validate

that everything is correct before finally provisioning the REST Endpoint.

3.2.6 SmartConnector Portal

SmartConnector includes an integrated web portal user interface which is installed along with the

service. This portal is the primary method to configure Processors, Endpoints, and EWS Servers as well

as monitor and control all aspects of SmartConnector. For more information please refer to the

SmartConnector Installation and Configuration Guide.

3.2.7 Worker Manager and Workers

Workers represent the threads in SmartConnector that execute Processors. The number of available

Workers is configurable but is generally limited by the host system hardware. When not actively

running a Processor, Workers are inactive, waiting for a command from the Worker Manager. In this

state, Workers consume virtually no system resources.

The Worker Manager is responsible for selecting a Processor Configuration, instantiating its defined

Processor and passing it off to an idle Worker for execution. The Worker Manager also listens to input

to start or stop a Processor or EWS Server as required.

3.2.8 Extension

The term “Extension” is used to define any class assembly which contains code which can run in

SmartConnector. Extensions can contain Processors, EWS Server Hosts, RestProviders, and any

combination of these. Extensions are written by SmartConnector Developers to solve an application

problem.

3.2.9 Persistent Data Store

SmartConnector is backed by a SQL database to persist all manner of data including setup parameters,

configuration data, schedule data, and EWS server data. SmartConnector also provides a Processor

Page 10: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 9 of 86

Values data store that Processors can access directly. This data store can be used to save state between

run iterations of the Processor or to enable collaboration between multiple Processors.

3.2.10 In-Memory Cache

In addition to a persistent data store, SmartConnector provides a mechanism to have a volatile in-

memory cache of data. A singleton class available to any Processor, RestProvider, or EWS Server which

provides strongly typed access to any data the author wishes to store.

3.2.11 Logging

SmartConnector provides an integrated logging framework. Logging levels of Info, Status, Error, Debug,

and Trace are extensively used throughout the SmartConnector runtime and public libraries. The Logger

is also available to Extension authors for adding their own log information to the common log file

output.

3.2.12 Licensing

SmartConnector’s framework is licensed. Commercial and development licenses can be obtained at

www.smartconnectorserver.com.

Additionally, SmartConnector provides all the hooks necessary for developers to license any Extension

component. These Licenses are managed by the developers themselves also using

www.smartconnectorserver.com.

Page 11: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 10 of 86

4 Common Data Flows SmartConnector was designed to bridge the gap between systems; specifically, Schneider Electric

Building Management systems and third-party systems and data sources. How one designs these

systems depends on many factors beyond the scope of this document. However, the patterns and data

flows that are required are frequently repeated from solution to solution. These patterns and

recommendations on how to implement them will be discussed in the sections that follow.

4.1 Retrieving Data from an EWS Server

While StuxureWare Building Operation ASs and ESs are the most likely EWS servers you will be

integrating with, any system which adheres to either the EWS 1.1 or EWS 1.2 specification can serve

data which can be consumed by your SmartConnector enabled solution.

SmartConnector provides the EwsClient class for this purpose. While EWS is not difficult to consume,

SmartConnector has abstracted out common read oriented tasks into higher order helper classes. These

tasks handle some of the idiosyncrasies in EWS, shielding the user from issues such as paging,

subscribing and renewing, and knowing when to call GetAlarmEvents versus GetUpdatedAlarmEvents.

These classes are defined below.

4.1.1 EwsClient

This class provides all methods and proxy data classes needed to consume any EWS 1.1/1.2 server.

4.1.2 AlarmItemReader

This class provides the functionality to retrieve paged data sets of AlarmItem from any EWS 1.1/1.2

server.

4.1.3 ValueItemReader

This class provides the functionality to retrieve paged data sets of ValueItem from any EWS 1.1/1.2

server.

4.1.4 HistoryItemReader

This class provides the functionality to retrieve paged data sets of HistoryRecord from any EWS 1.1/1.2

server.

4.1.5 SubscriptionReader

This class provides the functionality to receive subscription notifications from any EWS 1.2 server. All

aspects of subscription management are handled for the consumer.

4.2 Providing Data to an EWS Client

While StuxureWare Building Operation ASs and ESs are the most likely EWS clients you will be

integrating with, any system which can consume an EWS 1.1 or EWS 1.2 feed can be integrated with

your SmartConnector enabled solution. SmartConnector provides fast, EWS 1.2 compliant, database

backed, EWS Servers for this purpose.

Page 12: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 11 of 86

Where the server data originates depends on which technique works best for your solution. Generally,

there are three data management techniques used to manage EWS data: asynchronous data

management, synchronous data management, or a hybrid approach which uses both asynchronous and

synchronous methods. While each technique comes with its own complexities and pros and cons,

asynchronous data management is the easiest method to implement and the more common technique

used.

4.2.1 Asynchronous Data Management

Asynchronous data management involves provisioning a native SmartConnector EWS server via the

portal or through code using the EwsServerDataAdapter class. Please refer to the SmartConnector

Installation and Configuration Guide for more information.

Regardless of the provisioning approach, the data served is stored in the SmartConnector database and

managed asynchronously to the inbound client calls. This is typically done with one or more custom

Processors which maintain the data using the aforementioned EwsServerDataAdapter class.

Pros:

• Serve performance is fast.

• Simpler to implement.

Cons:

• Served data may be stale between refresh cycles of the update Processor.

4.2.2 Synchronous Data Management

Synchronous data management involves provisioning a native SmartConnector EWS server via the portal

(see SmartConnector Installation and Configuration Guide). Once provisioned, all data is retrieved and

served synchronous to the client request. This is accomplished by creating custom EWS Server request

processors for every EWS method to be supported.

Pros:

• Greater customization is achievable.

Cons:

• Serve performance is typically slower.

• Harder to configure.

• More involved to implement.

4.2.3 Hybrid Data Management

While synchronous data management offers a higher degree of customization, most solutions typically

only require synchronous actions to support write, force, and unforce methods. In these or similar

situations, a hybrid approach is usually the best.

Page 13: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 12 of 86

Hybrid solutions are asynchronous solutions where only those method(s) which need to be performed

synchronously are overridden from the base implementation.

Pros:

• Serve performance is fast for reads.

• Allows selective customization.

Cons:

• Served data may be stale between refresh cycles of the update Processor.

• Harder to configure.

• Incrementally more involved to implement.

4.3 Providing Data to a Third Party

While StuxureWare Building Operation ASs and ESs are the most likely sources of the data you will be

providing to third parties, the manner in which you provide this data will largely be based on the

capabilities of the third party. If the third party can consume the EWS SOAP endpoint, no further

customization is needed. Unfortunately, this is unlikely. More likely are those scenarios where the

client can be classified as either an active or passive participant.

4.3.1 Active Third Party

An active third party is one that directly consumes either a SOAP or REST endpoint which

SmartConnector will serve. If EWS is supported then no further customization is required beyond what

is outlined in Providing Data to an EWS Client above.

If only EWS is not supported, there are still options available to you in SmartConnector.

4.3.1.1 RESTful EWS Proxy

SmartConnector provides infrastructure to provision REST endpoints which can be used to serve data

from either a native SmartConnector EWS Server or any EWS Server based on the standard SOAP

protocol. To be clear, this is not a port of EWS to REST, rather it is a comprehensive and truly RESTful

approach was used complete with throttling, authentication, and paging. See SmartConnector

Installation and Configuration Guide and SmartConnector EWS REST API Gateway for more information.

4.3.1.2 Custom REST Endpoint

As with most of SmartConnector, you can also create your own customized REST server using the

throttling, authentication, and paging components available from the framework.

4.3.2 Passive Third Party

A passive third party is one that has its own API integrators are required to use to push data into it. This

is typically implemented purely with Processors which perform all of the necessary read/write

operations.

Page 14: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 13 of 86

5 Develop an Extension Regardless of whether you are writing a custom Processor, EWS Server, or REST Provider, you will need

to create at least one SmartConnector Extension to contain it all. A SmartConnector Extension is a

specially annotated .NET assembly which contains all of the pieces for your SmartConnector solution. If

you prefer, you could create multiple Extensions to organize different solution components separately.

Review the Licensing Your Extension section before deciding if one or multiple Extension assembles are

best for your situation.

The best way to describe how to develop an Extension is to actually develop an Extension. The

remainder of this guide will do just that. We will design an Extension and develop the code to

implement it. After the code is developed, we will write some unit tests to verify our Extension works

properly in a development environment. Then we will deploy our Extension to a SmartConnector

runtime, configure it, and verify that it functions as intend. Finally, we will add licensing to our

Extension and update the deployed runtime.

Some of the code steps below may seem obvious for seasoned developers. Have patience as the pace

will quicken as you read on. All screen shots, code syntax, and steps are for C# using Visual Studio 2017.

Other languages and development environments may have slightly different steps.

The following methodology is by no means the only way to develop Extensions, but it is the preferred

methodology used by Buildings Labs.

You can follow along with the sections below or jump right in and review the final source code on

GitHub at https://github.com/BuildingsLabs/SmartConnectorSamples. Other samples can also be found

in this repository./

5.1 Problem Statement

A requirement exists to obtain current weather data (temperature, pressure, and humidity) and a three

day weather forecast (Date, High Temp, Low Temp, Pressure, Humidity, and Forecast) from a third party

weather service. This data is to be served so it can be consumed by a generic EWS client. The EWS

client should also be able to change the target city of the forecast, but not inadvertently change any of

the data obtained from the web service. If latency exists between changing the city and weather data

getting updated, the EWS data should report that in some way. The server should also maintain

historical data for the current conditions.

5.2 The Design

To accomplish this we will need an EWS Server to serve the data. We will use the “hybrid” data

management described above with two Processors, SetupProcessor and UpdateProcessor, and a

CustomSetValuesProcessor in the EWS Server to manage the change of City request.

We will pull weather data from the free weather service https://home.openweathermap.org. You will

need to register as a developer for this site and obtain your own API key.

Page 15: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 14 of 86

Our design will look like Figure 2.

Figure 2: SmartConnector.WeatherExtension Architecture

5.2.1 SetupProcessor

• Create a configurable EWS Server (if one does not exist).

• Verify the EWS Server settings are as intended to prevent against inadvertent change.

• Provision the proper EWS data objects (ContainerItem, ValueItem, HistoryItem etc.) which

will contain forecast and current conditions.

• This Processor should run on an occasional schedule.

5.2.2 UpdateProcessor

• Connect to the EWS Server configured by the SetupProcessor.

• Read a predefined City input from the EWS Server, obtain current conditions and forecast from a

weather service, and update the EWS Server with this data.

• Manage historical weather data.

5.2.3 Custom EWS Server

• Provide custom SetValues functionality such that if the City is changed, will immediately set the

State of all current conditions and forecast data to ‘Uncertain’.

Page 16: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 15 of 86

• All other behavior will be standard.

Let’s get started…

5.3 Configure NuGet Feed

Before we code anything, we need to configure Visual Studio to have access to SmartConnector’s public

libraries. These libraries are distributed via NuGet packages hosted on a private feed at

www.myget.org. To access this feed, you need to register at www.smartconnectorserver.com. After

you have authenticated on this site, click “Send a request to become a SmartConnector Developer” link

and supply the required information.

After you are granted access by Buildings Labs, you will receive an email directly from MyGet. Follow

the instructions contained in that email and then continue on with the steps in this section.

1. From Visual Studio, select Tools-Options-NuGet Package Manager option.

2. Click Package Sources.

3. Click + to add a new source.

4. At the bottom of the dialog, enter a Name of “SmartConnector” and a Source of

https://www.myget.org/F/mongoose/auth/YOUR_API_KEY/api/v2 where YOUR_API_KEY is your

personal API key from MyGet.

5. Click Update.

6. The dialog should look similar to Figure 3.

7. Click OK.

Figure 3: NuGet Package Manager Settings

Page 17: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 16 of 86

5.4 Creating Extension Assembly

To review, an Extension is a specially annotated .NET class library assembly. You may want to start with

a class library project but when we get to writing unit tests, we’ll want to keep that code separate so we

don’t deploy our test code to a production environment. Let’s start with an empty solution.

5.4.1 Create an Empty Solution

1. Start Visual Studio.

2. From the Start page, click “New-Project”.

3. From the “New Project” dialog select “Installed-Templates-Other Project Types-Visual Studio

Solutions” from the tree on the left.

4. Choose the “Blank Solution” from the list on the right.

5. Choose the appropriate .NET framework you want to target.

6. Supply a unique “Name” for your Solution (e.g. SmartConnectorSamples).

7. Select the location you wish to have your code saved to.

8. Click “OK”.

Figure 4: Create Blank Solution

5.4.2 Add Class Library Project

Now that we have our empty solution, let’s add our Extension class library to it.

1. From the Solution Explorer, click “File-New-Project”.

2. From the “New Project” dialog select “Installed-Templates-C#” from the tree on the left.

3. Choose the “Class Library” from the list on the right.

4. Choose the appropriate .NET framework you want to target.

5. Choose “Add to Solution” and chose the solution you just created.

6. Supply a “Name” for your Extension Assembly (e.g. SmartConnector.WeatherExtension).

7. Click “OK”.

Page 18: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 17 of 86

Figure 5: Add Extension Assembly to Solution

5.4.3 Annotate Your Extension Assembly

The Portal displays assembly information to the user for both Processor and Endpoint Configurations as

well as for EWS Servers. Additionally, this information is displayed to the user during step one of the

corresponding “add” workflow for each type. This information is extracted from the AssemblyInfo file

in your class library.

1. Open up the AssemblyInfo.cs file in the root of your class library project.

2. Enter useful and descriptive information for:

a. AssemblyDescription

b. AssemblyCompany

c. AssemblyCopyright

d. AssemblyVersion

5.5 Processor Development (Setup Processor)

For our solution, we will be writing two Processor subclasses. Let’s start with the SetupProcessor.

5.5.1 Add Processor Class

1. Right click the project icon for your Extension Assembly in the Solution Explorer pane and select

“Add-Class”.

2. Name the class SetupProcessor. By convention, you should end the name with “Processor”.

3. Click “Add”.

4. Make the class public.

5. Subclass Processor.

Page 19: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 18 of 86

Figure 6: Add Processor Class

You will notice Visual Studio complaining (red syntax highlighting) about Processor. If you click CTRL + .

to ask Visual Studio for hints, your environment should like something like Figure 7.

Figure 7: Processor Missing Reference

Visual Studio doesn’t yet know the Processor base class. We need to add a reference to one of the

SmartConnector NuGet packages.

5.5.2 Add NuGet Reference

1. Right click the “References” icon for your Extension Assembly in the Solution Explorer pane and

select Manage NuGet Packages.

2. Select the “SmartConnector” packages source you configured above.

3. Confirm that “Include prerelease” is not checked.

Page 20: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 19 of 86

4. Click Browse. You should see something like Figure 8.

Figure 8: NuGet Package Manager Browsing SmartConnector Feed

5. Select “Mongoose.Process”.

6. Click “Install”

Visual Studio will install all dependent packages automatically. At this point, go back to your processor

code and click CTRL + . again. Now Visual Studio is telling you to add a using Mongoose.Process;

directive. Select that option.

Alas, Visual Studio is now complaining about the SetupProcessor class. Click CTRL + . one more time

and choose “Implement Abstract Class”. Your code should look like Figure 9.

Page 21: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 20 of 86

Figure 9: Processor Subclass Ready for Custom Code

5.5.3 Writing Your Code

5.5.3.1 IsLicensed

By default, SmartConnector assumes that you will be licensing all component parts of your Extension.

This is optional. If you do NOT wish to license your Processor, you do need to add an override for the

IsLicensed property as shown in Figure 10. For now, we will override this in the SetupProcessor.

We’ll come back to this later when we add licensing.

Figure 10: IsLicensed Override

5.5.3.2 Annotate Processor Class

Remember, SmartConnector was designed to be highly flexible and configurable. As developers it is our

job to make this configuration as easy as possible for those doing the deployments and configurations.

The first way to do this is to provide a default name and description for Processor Configurations based

on this Processor. By annotating our SetupProcessor with the ConfigurationDefaultsAttribute as

shown in Figure 11 we can provide some context on what the class will do.

Page 22: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 21 of 86

Figure 11: SetupProcessor – Configuration Defaults Attribute

5.5.3.3 Configurable Properties

As you write your code, you will almost always need input not available to you at design time. This

information will need to be obtained from the person configuring your code in the Portal. To facilitate

this, every public read/write property in your Processor will be considered a configurable property. All

configurable properties will be extracted from your code when a Processor Configuration is generated.

This is true for both value type properties and reference type properties as we shall soon see. The

ConfigurationIgnoreAttribute can be used if you want to hide an otherwise configurable property.

Let’s take a look at this in practice. Our SetupProcessor requires the following inputs in order to

perform its intended function:

• ServerName: Name of the EWS Server to create. Required.

• Realm: HTTP Digest authentication realm value we want to use. Optional

• EwsAddress: HTTP endpoint address we want to receive EWS requests on. Required.

• UserName: Name of the EWS User to use when authenticating. Required.

• Password: Password for the EWS User to use when authenticating. Required.

A quick look at these properties and you will notice that we have some properties that are required,

some that are optional and some that are going to contain sensitive information. Can SmartConnector

handle all of that? Have I mentioned that SmartConnector was designed to be highly flexible and

configurable?

Stubbing out these properties in our SetupProcessor class will result in what is shown in Figure 12.

Page 23: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 22 of 86

Figure 12: SetupProcessor – Properties (Take 1)

Something seems to be missing though. How does SmartConnector know what we want to be required

and what we want to be optional? How does SmartConnector know that the UserName and Password

properties contain sensitive information? To do that, let’s talk about validation.

5.5.3.4 Validation

Because of the configurable nature of SmartConnector, validation of the state of the Processor – loaded

from a Processor Configuration – is critical. In SmartConnector, Processor validation is based on the

.NET Validator class and does both schematic (attribute based) and semantic (interface based)

validation.

5.5.3.4.1 Schematic Validation

Schematic validation means that the instance of the class contains values that are what the author

schematically deemed acceptable. To achieve this, SmartConnector makes extensive use of the .NET

framework’s System.ComponentModel.DataAnnotations namespace. Any attribute found in that

namespace can be used to annotate a property in your Processor. Some of the more common ones you

will use are Range, Required, MinLength, MaxLength, and StringLength.

You can also author your own custom validation attribute by subclassing the .NET framework’s

ValidationAttribute class and SmartConnector will honor it. SmartConnector provides some of

its own specialized validation attributes in this manner. These are documented in the Appendix.

Knowing this, we can now update our code to require certain values.

Page 24: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 23 of 86

Figure 13: SetupProcessor – Properties (Take 2)

5.5.3.4.2 Semantic Validation

”Semantic” refers to the type of validation which is beyond the obvious schematic-based validation. In

other words, meaning or context is required. Semantic validation is based on the .NET framework

IValidatableObject interface. Since Processor implements this interface, developers can optionally

override the Validate method to perform this type of contextual validation to ensure the proper state

of the Processor.

In our SetupProcessor we have a condition which could warrant Semantic Validation. It is as common

security best practice to not allow a user name and a password to be the same. We can implement that

as shown in Figure 14.

Page 25: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 24 of 86

Figure 14: SetupProcessor – Validate Override

Note: if you are not familiar with the yield keyword, a good reference can be found here.

5.5.3.4.3 Deep Validation

SmartConnector enhances the way the .NET Validator class validates by performing a “deep” graph

traversal, validating the entire Processor instance. SmartConnector’s GenericValidator is used to

perform this traversal. GenericValidator not only validates the properties of the Processor subclass,

it also traverses into any property that is a reference type that implements either the ITraversable or

IEnumerable interface.

5.5.3.5 Configuration Aids

At this point, our SetupProcessor class can be properly validated with what we require, but how do we

tell SmartConnector what is sensitive information? And how do we help users to configure it?

For that we will review three additional important attributes.

5.5.3.5.1 DefaultValueAttribute

The DefaultValueAttribute is part of the .NET framework but it’s not a very well understood

attribute. It is enumerated here because SmartConnector fully supports its use during Processor

Configuration creation if any configurable property is decorated with it. When a Processor

Configuration is first created, the default value will be what you, the developer, set. This is true

regardless of whether the property is a string, int, long, decimal, or even an enumeration. These

properties will still be editable, but at least the initial value is controlled by you the developer.

5.5.3.5.2 TooltipAttribute

A Processor author can decorate any configurable property with the TooltipAttribute. The contents of

the “tooltip” will be rendered in the SmartConnector Portal when the user clicks on an icon adjacent to

the property label. This can be useful to provide instructions and guidance to Portal users – or basically

tell users what the property does.

5.5.3.5.3 EncryptedStringAttribute

Configuration properties derived from items with this attribute will be encrypted when they are written

to the SmartConnector database and decrypted when they are read from the database.

With this information, we can now able to complete our SetupProcessor properties as shown in Figure

15.

Page 26: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 25 of 86

Figure 15: SetupProcessor – Properties (Take 3)

5.5.3.6 Execute_Subclass

When we implemented the required abstract Processor (see Figure 9), Visual Studio stubbed out the

main entry point for all custom logic. It is here where our actual “work code” will go. Before we

implement our custom logic, let’s take a moment to review some general topics about this method.

5.5.3.6.1 Return Value

The return type is a list of Prompt instances. This can be used to report any problems encountered

when your code was executed. Presently, these are only used for logging purposes (logging in this case

is done for you automatically). If no messaging is to be conveyed, then an empty list should be

returned.

5.5.3.6.2 Looping

Loops in your Processor code are expected. Well written Processor code must still be responsive to

external input from users, the operating system, or the SmartConnector runtime. To achieve this, the

base class has a CancellationToken property that is managed by the SmartConnector runtime.

Processor code must monitor this if loop constructs of any type are present – even if they are “short”

loops. This can be done in two different ways:

5.5.3.6.2.1 IsCancellationRequested

The protected IsCancellationRequested property can be used to determine if a stop is pending. The

method should then terminate as soon as possible after performing any required actions. This is

typically used as shown in Figure 16.

Page 27: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 26 of 86

Figure 16: IsCancellationRequested Usage

5.5.3.6.2.2 CheckCancellationToken()

A somewhat less graceful albeit faster exit can be achieved by calling the protected

CheckCancellationToken method. This approach should only be used if an uncontrolled and

immediate termination of the method is acceptable as it will cause a TaskCancelledException to be

thrown if a stop request is pending. SmartConnector will call the virtual CleanupBeforeCancellation

method prior to throwing the exception if cleanup of any type is required. This is demonstrated in

Figure 17.

Figure 17: CheckCancellationToken Usage

Page 28: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 27 of 86

5.5.3.6.3 Running Long

A Processor is expected to complete its execution in a short, finite amount of time. This is required for a

variety of reasons but most importantly so other Processors can also execute. Remember there are only

a finite number of configurable threads for Processor execution and if there are several Processor

Configurations hogging the available threads other work may not get executed as expected.

If a Processor has not completed in the time configured in the Portal Settings, the SmartConnector

runtime will terminate the thread it is executing on.

For a variety of reasons, it may not always be practical to design a conforming Processor which runs in a

short amount of time. SmartConnector runtime can accommodate this situation. Developers need only

implement the ILongRunningProcess as shown in Figure 18.

Figure 18: ILongRunningProcess Usage

5.5.3.6.4 Finishing Up

Before we implement our Execute_Subclass override, let’s review the code we have so far. It should

look similar to Figure 19.

Figure 19: SetupProcessor (Take 1)

From the requirements, we can stub out the functionality we need with comments as shown in Figure

20.

Page 29: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 28 of 86

Figure 20: SetupProcessor – Execute_Subclass (Take 1)

Much like the God Object is an anti-pattern, the “god method” is an anti-pattern as well – and you won’t

see any code like that in these examples. Adding some methods brings us to Figure 21.

Figure 21: SetupProcessor – Execute_Subclass (Take 2)

Let’s review.

• Make sure we can connect to an EWS Server.

An instance of the EwsServerDataAdapter is what we will be using to bootstrap and configure the

native SmartConnector EWS Server. There is no public constructor for this class. Rather, you need to

use one of the two static methods to acquire an instance. Figure 22 illustrates how we can use that in a

Lazy Loading design pattern to accomplish what we need.

Page 30: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 29 of 86

For “Create New” we will just use the native EWS Server implementation. We’ll come back to this after

we have written our custom EWS Server.

Figure 22: SetupProcessor – Lazy Load an EwsServerDataAdapter

• If the server isn’t running, start it now.

Our connected EwsServerDataAdapter property (DataAdapter) can do this for us as shown on line 66 in

Figure 20. Any required start request will occur asynchronously but that’s OK for our purposes.

• Confirm that the server settings are how we want them to be.

The EwsServerDataAdapter has all of the required methods to do this as shown in Figure 23.

Page 31: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 30 of 86

Figure 23: SetupProcessor – EnsureServerParameters

• Add the fields a client can use to “set” the location.

In order to accomplish this step, we are going to need to bootstrap ContainerItem, ValueItem, and

HistoryItem instances in our server. While we can and will use the DataAdapter property to do this,

we will need to set the AlternateId (the EWS Id) for each entity. If we think ahead for a moment, we’ll

realize that we are also going to need this information in both the UpdateProcessor and

CustomSetValuesProcessor. There are several ways to do this, but we won’t be using Magic Numbers

here. Rather we will create a ServerHelper static class for this purpose as shown in Figure 24.

Figure 24: ServerHelper Class (Take 1)

Page 32: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 31 of 86

Now we can add some helper methods that will actually create/update our EWS Items as shown in

Figure 25.

Figure 25: SetupProcessor – Ensure EWS Items

And finally, we can add the fields a client can use to “set” the location as shown in Figure 26.

Figure 26: SetupProcessor – AddUserInputFields

On line 228, you can see that we are making the cityName ValueItem not writeable and if there is no

value in the cityName ValueItem, we are setting its state to Uncertain to indicate to consumers that

our code hasn’t yet acknowledged a change to the city ValueItem.

• Add the folders and data points where we will write the current weather conditions.

Page 33: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 32 of 86

Following the similar approach from the prior step, and leveraging those helper methods, we can add

placeholders for the current conditions as seen in Figure 27.

Figure 27: SetupProcessor - AddCurrentConditionPlaceHolders

• Add the folders and data points where we’ll write the forecast.

And again for the forecast data as seen in Figure 28.

Figure 28: SetupProcessor – AddForecastPlaceHolders

• Return any issues

Page 34: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 33 of 86

We can wrap up our code by returning any issues. Since we’re not accumulating any, we’ll just return an

empty list as shown on line 81 of Figure 21.

Before me move on, we should make sure we cleanup anything that’s IDisposable. Our

EwsServerDataAdapter backing property does implement IDisposable so let’s make sure we dispose

of that properly.

Since Processor is itself IDisposable we only need to override the Dispose method and the runtime

will handle calling it for us at the proper time. Of course we must still call the base implementation

since it also needs to do it’s cleanup. Figure 29 shows one way to handle this cleanly.

Figure 29: Dispose Override

And with that, we’ve completed the SetupProcessor; on to the UpdateProcessor.

5.6 Processor Development (UpdateProcessor)

Now that we are ready to start on the UpdateProcessor, we will need a new class for that. You should

be able to follow the steps outlined above to add your class, annotate it with the

ConfigurationDefaultsAttribute and override the IsLicensed property to temporarily disable

Extension Licensing. You won’t have to configure your NuGet source as that only needs to be done once

per project. The result should look something like Figure 30.

Page 35: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 34 of 86

Figure 30: UpdateProcessor (Take 1)

5.6.1 Configurable Properties

For our UpdateProcessor, we require the following inputs in order to perform its intended function:

• ServerName: Name of the EWS Server to create. Required.

• UserName: Name of the EWS User to use when authenticating. Required.

• Password: Password for the EWS User to use when authenticating. Required.

• ApiKey: API access key for our developer’s account in https://home.openweathermap.org.

Required.

• UpdateCurrentConditions: Should update current weather conditions values only.

• UpdateForecast: Should update Forecast values only.

Knowing what we know now about attributes. It shouldn’t take us long to stub out these properties as

shown in Figure 31.

Figure 31: UpdateProcessor – Properties (Take 1)

Hopefully, you will look at this code and your own particular warning bells will be going off. Three of the

properties we needed in the SetupProcessor we need again here. Furthermore, we’re going to need a

DataAdapter instance just like we did in the SetupProcessor, and some common validation and

cleanup. Perhaps some refactoring of our code is in order.

5.6.2 Time to Refactor

Let’s start by creating a new WeatherProcessorBase class and have that subclass Processor. Adding in

our common properties and validation brings us to Figure 32.

Page 36: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 35 of 86

Figure 32: WeatherProcessorBase (Take 1)

Then we can add in our lazy loaded DataAdapter. For this we’ll make a minor tweak. Only the

SetupProcessor should actually create the EWS Server. The UpdateProcessor should just exit

gracefully if the server isn’t available (i.e. it’s null). This should look like Figure 33.

Page 37: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 36 of 86

Figure 33: WeatherProcessorBase (Take 2)

Finally we can move our Dispose from Figure 29 here to handle the proper cleanup required.

We can now refactor SetupProcessor and UpdateProcessor to be a subclass of our new base class and

remove the redundant properties. This should look like Figure 34 and Figure 35 respectively.

Page 38: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 37 of 86

Figure 34: SetupProcessor – Final Version

Figure 35: UpdateProcessor – (Take 2)

5.6.3 Execute_Subclass

From the requirements, we can stub out the functionality we need with comments as we did previously

in the SetupProcessor. The results are shown in Figure 36.

Figure 36: UpdateProcessor – Execute_Subclass (Take 1)

Page 39: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 38 of 86

Adding some code brings us to Figure 37.

Figure 37: UpdateProcessor – Execute_Subclass (Take 2)

Let’s review what we did.

• Make sure we can connect to an EWS Server.

Line 36 of Figure 37 is exactly what we did in the SetupProcessor. If there is no server (e.g.

IsConnected == false) we will just report that via a Prompt and exit.

• Retrieve CurrentCity ValueItem

Lines 39-50 of Figure 37, retrieves the EwsValueItem from our DataAdapter instance. If there is no

EwsValueItem, (e.g. currentCity == null) we will just report that via a Prompt and exit.

• Perform Updates

Line 53-56 of Figure 37 calls DoUpdates. If the method fails to perform the updates for currentCity we

want to make sure our EWS data can report that condition (this was a requirement enumerated above).

Before we get to that, let’s write the actual update code.

Since the UpdateProcessor can be configured to update either the current conditions and/or the

forecast, we can write that method as shown in Figure 38. If updating either the current conditions or

forecast fails, we’ll return that to the calling routine.

Page 40: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 39 of 86

Figure 38: UpdateProcessor – DoUpdates

Drilling into DoUpdateCurrentConditions we can frame out the work we need to do as shown in Figure

39.

Figure 39: UpdateProcessor – DoUpdateCurrentConditions (Take 1)

First we need to create the web request we will send to the weather service and then execute that

request as shown in Figure 40.

Page 41: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 40 of 86

Figure 40: UpdateProcessor – DoUpdateCurrentConditions (Take 2)

Assembling and executing the HTTP request are done with the helper methods shown in Figure 41.

CreateWeatherRequest uses the SmartConnector QueryBuilder class to establish the HTTP request,

complete with query parameters, to be made as dictated by the weather service API we are using.

RequestWeatherData executes the HTTP request. But how does it know what type to return? For that,

a code generator such as http://json2csharp.com/ was used to generate C# POCO classes from sample

JSON responses from the weather API.

Page 42: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 41 of 86

Figure 41: UpdateProcessor – CreateWeatherRequest

Now that we know can make the HTTP request, we can complete the DoUpdateCurrentConditions

method as shown in Figure 42.

Page 43: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 42 of 86

Figure 42: UpdateProcessor – DoUpdateCurrentConditions (Take 3)

When we don’t receive a successful response from the weather service, we’ll exit

DoUpdateCurrentConditions as shown on line 89 of Figure 42. But what are we doing with lines 98 -

112? The weather service we are using doesn’t provide “real time” values. Rather it updates current

conditions periodically. By only updating our current conditions with newer data we wont inadvertently

create “history” when the change of value occurs.

Following in kind we can complete DoUpdateForecast as shown in Figure 43.

Page 44: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 43 of 86

Figure 43: UpdateProcessor – DoUpdateForecast

At this point we are almost done. If you recall, we still have that TODO left to clean up (line 55 of Figure

37). Looking at the ModifyValueItemValue calls in Figure 42 and Figure 43 you will notice that we are

passing a value of EwsValueItemStateEnum.Good into the state parameter. The

EwsServerDataAdapter will set the state along with the updated value. In contrast, when we fail to

receive a response from the web service, we should update all of those same EwsValueItem instances

with a state of EwsValueItemStateEnum.Uncertain.

Since we are probably going to need this again in our custom EWS Server implementation, let’s update

the ServerHelper class with this logic as shown in Figure 44.

Page 45: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 44 of 86

Figure 44: ServerHelper (Take 2)

Now we can complete the UpdateProcessor code as shown in Figure 45.

Page 46: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 45 of 86

Figure 45: UpdateProcessor – Execute_Subclass (Take 3)

• Return any issues

We can wrap up our code by returning any issues. Since we’re not accumulating any, we’ll just return an

empty list as shown on line 56 of Figure 45.

5.7 Custom EWS Server Development

The final step in our SmartConnector solution development is to customize the native SmartConnector

EWS Server behavior in our Hybrid Data Management solution. Since all of the data served to EWS

clients will be done so normally (i.e. no customization is required) the only customization we do need is

address the latency that will exist between an EWS client changing the city and our UpdateProcessor

updating the current conditions and forecast for that new city.

This latency can be addressed by setting the State value of the served EwsValueItem to Uncertain. Of

course we already did this in the ServerHelper. We only need to know where to inject that logic.

5.7.1 Add ServiceHost Class

1. Right click the project icon for your Extension Assembly in the Solution Explorer pane and Select

Add-New Folder.

2. Add an empty folder named “EwsServer”.

3. Right click the “EwsServer” folder you just added select Add-Class.

4. Name the class CustomEwsServiceHost. By convention, you should end the name with

“ServiceHost”.

5. Click Ok.

6. Make the class public.

7. Subclass EwsServiceHost.

Page 47: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 46 of 86

You will notice Visual Studio complaining (red syntax highlighting) about EwsServiceHost. If you click

CTRL + . to ask Visual Studio for hints, your environment should like something like Figure 46.

Figure 46: ServiceHost Missing Reference

Visual Studio is missing a reference to a subclass of EwsServiceHost that it also requires. Allow it to

“Add reference to ‘System.ServiceModel’”.

Alas, Visual Studio is still complaining. Click CTRL + . one more time and choose “Implement Abstract

Class”. Your code should look like Figure 47.

Figure 47: ServiceHost Subclass Ready for Custom Code

Fortunately, most of the code here is boilerplate code that we can easily replace as shown in Figure 48.

Page 48: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 47 of 86

Figure 48: CustomServiceHost (Take 1)

Reviewing the code from Figure 48 we see that we opted out of licensing (IsLicensed returns false)

and threw a NotImplentedException in ValidateCustomLicenseFeatures. That’s fine, but we also

added a call to AddServiceEndpoint in ProvisionEndpoint. AddServiceEndpoint and CreateBinding

are WCF methods used to “wire-up” request handlers. The abstract ProvisionEndpoint method is

simply the SmartConnector frameworks way of reminding you that if you are subclassing

EwsServiceHost, you must do this yourself. The type IDataExchange (on line 38) doesn’t actually have

to be used here, but if you do want to extend the interface of the SOAP service, you will need to pass in

an interface type that is at least a subclass of IDataExchange. Remember this is all boilerplate code. In

virtually every custom EWS Serve extension you write, you can copy lines 19-40 as is.

If you’re paying attention, you may realize we still haven’t wired in our custom code. How do we do

that? For that, let’s revisit the constructor in lines 13-16 of Figure 48. The constructor code generated

was Visual Studio’s best guess implementation when we asked it to ““Implement Abstract Class””.

Unfortunately, it didn’t guess correctly. What is needed is for us to supply the type name for a subclass

of MongooseDataExchange. For now, we can re-write the constructor as shown in Figure 49 and we will

create the CustomDataExchange class shortly.

Page 49: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 48 of 86

Figure 49: CustomServiceHost (Take 2)

5.7.2 Add DataExchange Class

1. Right click the “EwsServer” folder in the Solution Explorer and select Add-Class.

2. Name the class CustomDataExchange. By convention, you should end the name with

“DataExchange”.

3. Click Ok.

4. Make the class public.

5. Subclass MongooseDataExchange.

You will notice Visual Studio complaining (red syntax highlighting) about MongooseDataExhange. That’s

because we need to supply a different NuGet reference. Follow the steps outlined above and add a

reference to “Mongoose.Ews.Server”.

Alas, Visual Studio is still complaining. Click CTRL + . one more time and “Add reference to

‘System.Web.Services’”. Your code should look like Figure 50 .

Page 50: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 49 of 86

Figure 50: CustomDataExchange (Take 1)

At first blush, this may look strange to you. We haven’t overridden anything and there are no abstract

methods or properties to implement. That is correct. If we left our code like this, we will have changed

nothing and have the identical functionality as a native SmartConnector EWS Server. Of course that’s

not why we are doing this.

To inject our custom “Set Values” functionality, we need to add an override as shown in Figure 51.

Figure 51: CustomDataExchange (Take 2)

Page 51: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 50 of 86

With that completed, we only need to create the CustomSetValuesProcessor class.

5.7.3 Add Custom Request Processor Class

Each request that is received from an EWS SOAP client to a native SmartConnector EWS Server is

handled by a unique request processor. Using the Object Browser (Select View-Object Browser from in

Visual Studio) a complete list of all available request processors can be viewed as shown in Figure 52.

Figure 52: Object Browser – Mongoose.Ews.Server.Processor Namespace

For our SmartConnector Extension solution, we need to provide custom handling for the “SetValues”

method. So we’ll need to add another class for that.

1. Right click the “EwsServer” folder in the Solution Explorer and select Add-Class.

2. Name the class CustomSetValuesProcessor. By convention, you should end the name with

“Processor”.

3. Click Ok.

4. Make the class public.

5. Subclass MongooseSetValuesProcessor.

6. Override the SetValue method.

At this point your code should look like Figure 53.

Page 52: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 51 of 86

Figure 53: CustomSetValuesProcess (Take 1)

Remember, the only thing we want to add to the base functionality (i.e. persisting the change to the

database) is to address the latency that will arise between this call and UpdateProcessor acting on the

new city and updating the current conditions and forecast. For that, we can leverage the ServerHelper

method we added earlier. The result will look like Figure 54.

Figure 54: CustomSetValuesProcess (Take 2)

5.8 One Final Edit

Before we get to testing, we need to make one final change to the SetupProcessor code. Recall that in

Figure 22 we instructed the EwsServerDataAdapter to create an instance of a default native

SmartConnector EWS Server. Now that we have completed our custom version, we need to update the

CreateEwsServer method accordingly as shown in Figure 55.

Figure 55: SetupProcessor – CreateEwsServer (Take 2)

And with this, our SmartConnector Extension is complete; now on to testing!

Page 53: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 52 of 86

6 Testing an Extension Test-driven development is the norm in software development best practices these days. As such, this

approach is strongly recommended when developing SmartConnector Extensions. Choosing which unit

testing framework to use, however, is less clear. Whether you choose Visual Studio testing, NUnit, XUnit

or another framework is largely a matter of developer preference and a discussion topic that is beyond

the scope of this document.

For this guide, we will use the NUnit3 testing framework. As an incentive to using NUnit, Buildings Labs

provides a NuGet package to facilitate test writing with NUnit.

Before we can begin writing tests, we will need to complete some housekeeping steps.

6.1.1 Install a Test Runner

In order to execute the tests we will be writing we need a “test runner”. A “test runner” is an external

application or Visual Studio add-in that allows you to run or debug tests and view the results. If you use

ReSharper (licensed Visual Studio productivity extension), you can skip the remainder of this section as

ReSharper will be your test runner. If you don’t use ReSharper, continue reading.

Older versions of NUnit provided a Windows application to run tests and examine results. NUnit3 has

replaced this with a console based test runner. While sufficient for build environments, this approach is

not the suitable for running and debugging tests from within the Visual Studio IDE. For that, a free

Visual Studio add-in will be used. To install this add-in follow the following steps.

1. From Visual Studio, choose the “Tools-Extensions and Updates” menu.

2. Select “Online-Visual Studio Gallery” from the navigation tree at the left.

3. In the “Search” field at the top right, type in NUnit.

4. The first item listed should be “NUnit 3 Test Adapter” (See Figure 56).

5. Click “Download” immediately next to the description of the extension.

6. Click “Install” from the installation dialog.

7. Click “Restart now” to restart Visual Studio.

Page 54: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 53 of 86

Figure 56: Extensions and Updates – NUnit 3 Test Adapter

6.1.2 Install SmartConnector

SmartConnector was designed to allow creation of Extensions and testing of them to occur completely

outside the SmartConnector runtime environment. However, in order to fully test our Extensions, we

must leverage some of the Dependency Injection, Inversion of Control design patterns, and managed

functionality (caching, clients etc.) which SmartConnector provides.

In order to accomplish this, we will need a functional SmartConnector runtime. Follow the steps

outlined in the SmartConnector Installation and Configuration Guide to install SmartConnector on your

development computer. You must complete the entirety of section 4 in this guide.

Now that we have completed our prerequisites, we can begin to write unit tests for our SmartConnector

Extensions.

6.2 Create Unit Testing Project

We should always segregate test code from production code so that when it comes time to deploy our

code to production, we won’t include test code (and any references that are needed only to support our

tests). For that we need a new class library project.

1. From the Solution Explorer, click “File-New-Project”.

2. From the New Project dialog select “Installed-Templates-C#” from the tree on the left.

3. Choose the “Class Library” from the list on the right.

4. Choose the appropriate .NET framework you want to target.

Page 55: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 54 of 86

5. Choose “Add to Solution” and chose the solution you just created.

6. Supply a “Name” for your Test Assembly.

7. Click “OK”.

Figure 57: Add Test Assembly to Solution

6.2.1 Add Reference to Extension Assembly

Out test project will need a reference to our Extension Assembly.

1. Right click the “References” icon for your Test Assembly in the Solution Explorer pane and select

“Add Reference”.

2. In the “Reference Manager dialog”, select “Projects” and “Solution”.

3. Check the “SmartConnector.WeatherExtension” item listed.

4. Click “OK”.

6.2.2 Add Reference to SmartConnector

Our test project will also need a reference to the SmartConnector service EXE.

1. Right click the “References” icon for your Test Assembly in the Solution Explorer pane and select

“Add Reference”.

2. In the “Reference Manager” dialog, select “Browse” from the options on the left.

Page 56: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 55 of 86

3. Click the “Browse” button.

4. Navigate to the installation folder for SmartConnector.

5. Select “Mongoose.Service.exe”.

6. Click “OK”.

6.2.3 Transpose Configuration Settings

When Extension code runs in a production environment, it runs in the process space of SmartConnector

and as such, connection strings and encryption keys are read from the “Mongoose.Service.exe.config”

file. However, in our unit test environment, Extension code is invoked from unit tests running in the

process space of our Test Assembly. As a result, we need to copy the pertinent information to our Test

Assembly configuration file.

1. Right click the project icon for your Test Assembly in the Solution Explorer pane and select “Add-

New Item”.

2. Select “General” from the navigation pane on the left.

3. Select “Application Configuration File” from the options on the right (see Figure 58).

4. Click “Add”.

Figure 58: Add Application Configuration File to Test Assembly

5. Navigate to the installation folder for SmartConnector.

Page 57: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 56 of 86

6. Locate the “Mongoose.Service.exe.config”.

7. Open it with any text editor.

8. Locate the <connectionStrings> element and copy the entire contents between the opening

XML tag and the closing one </connectionStrings>.

9. In Visual Studio, locate the “app.config” file we just added and double click it.

10. Paste the connectionStrings element as shown in Figure 59.

11. Repeat steps 8-10 for the encryptionKey setting (include the appSettings element as shown).

Figure 59: Copy Configuration Settings to Test Assembly app.config

6.2.4 Add NuGet Reference

One final step remains. Buildings Labs supplies a NuGet package specifically intended for test purposes

is available.

1. Right click the “References” icon for your Test Assembly in the Solution Explorer pane and select

Manage NuGet Packages.

2. Select the “SmartConnector”.

3. Confirm that “Include prerelease” is not checked.

4. Click Browse. You should see something like Figure 8.

5. Select “Mongoose.Test”.

6. Click “Install”

6.3 Add Test Fixture Class (SetupProcessor)

By using the Mongoose.Test package we will create a unit test Fixture on a per Processor basis. Let’s

start with the SetupProcessor.

1. Right click the project icon for your Test Assembly in the Solution Explorer pane and select “Add-

Class”.

2. Name the class SetupProcessorFixture. By convention, you should end the name with

“Fixture”.

3. Click “OK”.

4. Make the class public.

5. Subclass SmartConnectorTestFixtureBase and IProcessorTestFixture<SetupProcessor>.

Page 58: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 57 of 86

You will notice Visual Studio complaining (red syntax highlighting) about the IProcessorTestFixture

interface. Using CTRL + . tells us we are missing a using directive for Mongoose.Test and

Mongoose.Test.Processors. Adding that we can CTRL + . one more time and “Implement Abstract

Class”. Your code should look like Figure 60.

Figure 60: SetupProcessorFixture (Take 1)

While Visual Studio is good at stubbing out known interfaces, it doesn’t supply everything we need here.

While convention dictates unit test method names should end in “Test” in order to make these methods

callable from the NUnit test runner, we must add the TestAttribute to them (along with a using

NUnit.Framework directive); which will bring us to what is shown in Figure 61.

Figure 61: SetupProcessorFixture (Take 2)

Let’s look at what’s needed for each method.

Page 59: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 58 of 86

6.3.1 FixtureOneTimeSetup_Base

NUnit provides attributes which can be used to decorate methods so that they run before and after the

actual tests run. These are useful for performing setup type operations required for any and all tests

included in the fixture. Much of what is needed to run a SmartConnector fixture is already handled for

you in the SmartConnectorTestFixtureBase class. Of course, there is one step that is typically needed

that can’t be performed for you in the base class; initialization of the inversion of control container.

Luckily this code is available as a static method from the Service reference itself. We can easily provide

the required code for FixtureOneTimeSetup_Base as shown in Figure 62.

Figure 62: SetupProcessorFixture – FixtureOneTimeSetup_Base

6.3.2 CreateTestableProcessor

Using the IProcessorTestFixture interface as a basis for writing unit tests for your Processor code

focuses on testing three major aspects: Processor Validation, Execution, and canceling a running

Processor. In all of these scenarios an instantiated Processor instance with valid properties is required.

CreateTestableProcessor provides that instance. To be clear, this method is not a test. Rather it is a

support method which the other Test methods will incorporate.

While an extension method of IProcessorTestFixture is available to do most of the work here, in

most cases more information is needed that the test code needs to supply. This is shown in Figure 63

Figure 63: SetupProcessorFixture – CreateTestableProcessor

Line 26 invokes an extension method which returns an instance of SetupProcessor with the default

values we set (see Figure 15). Line 29 adds the additional information our tests will need.

Page 60: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 59 of 86

6.3.3 ValidateTest

The ValidateTest is meant to work interactively with CreateTestableProcessor as shown in Figure

64. First, we call CreateTestableProcessor (line 40) and then run the extension method on lines 43-44

to confirm no issues are initially present. Following that, it is up to the test author to manually produce

validation issues and confirm that they are detected. The depth and breadth of this validation

confirmation is really up to the test writer and what is shown here is merely a guideline.

Figure 64: SetupProcessorFixture – ValidateTest

6.3.4 ExecuteTest

ExecuteTest mimics what the SmartConnector runtime does when a Processor Configuration is

commanded to run. In this case an extension method is available as shown in Figure 65.

6.3.5 CancelTest

CancelTest is similar to ExecuteTest except that shortly being invoked an abort is simulated to ensure

that your Processor exits in a timely fashion. As with ExecuteTest, an extension method is also

available for you to call to perform this test (see Figure 65).

Page 61: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 60 of 86

Figure 65: SetupProcessorFixture - CancelTest and ExecuteTest

6.3.6 Debugging Your Tests

Debugging your tests is as easy as opening the Test Explorer in Visual Studio (Test-Windows-Test

Explorer) to browse all detected unit tests as shown in Figure 66. It will be useful later when we have

tests with the same name to group them by fixture. This is accomplished by clicking the “Group By” icon

located in the top left corner of the Test Explorer and choosing “Class”.

Figure 66: Test Explorer

Once displayed you can either “Run” or “Debug” a single test, all tests in your fixture, or all tests in your

project. Debugging will allow you to set breakpoints in your code and step through to find any issues in

either your test code or processor code.

6.4 Add Test Fixture Class (UpdateProcessor)

Adding a test fixture for the UpdateProcessor should be fairly straightforward at this point. The results

are shown in Figure 67.

Page 62: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 61 of 86

Figure 67: UpdateProcessorFixture (Take 1)

Page 63: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 62 of 86

7 Deploying Your Extension Now that we have tested our Extension Assembly in a unit testing environment, we can deploy our code

to an actual SmartConnector runtime and confirm it is functional in a simulated production

environment.

7.1 Deploy Binary Files

Since our development is in .NET, deploying our Extension Assembly is straightforward. Simply copy the

binary output generated from a Release configuration, into the same folder location that the

SmartConnector Service EXE is located.

For our sample this means that we only need to copy the SmartConnector.WeatherExtension.dll file to

the SmartConnector service folder. If your actual Extension Assembly includes references to third party

DLLs, you need to include them as well.

7.2 Add Configuration (SetupProcessor)

To confirm that our Extension works as intended we will create Processor Configurations for each

Processor and confirm they function as designed. We’ll start with the SetupProcessor.

1. Open up a browser and navigate to http://localhost:8082 (note if you have changed the default

Portal address use that instead).

2. Authenticate with the proper portal credentials you established when you installed

SmartConnector.

3. Click “Configurations-Processor”.

4. Click “Add New”. You should see something like what is shown in Figure 68. If you do NOT see

“SmartConnector.WeatherExtension”, examine the log files to determine what the issue is. You

will need to first ensure “Portal” logging is not filtered out.

Page 64: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 63 of 86

Figure 68: Portal – Add Processor Configuration Page

5. Select “SmartConnector.WeatherExtension”

6. Click “Next”

7. Select “SmartConnector.WeatherExtension.SetupProcessor”

8. Click “Next”

9. Click “Finish”

10. Click the “Details” tab on the “Processor Configuration” page.

11. Verify the settings and make any changes from the default.

12. Save any changes.

13. Click “Validate”. If there are any issues, correct them now by repeating steps 11-12 and making

the appropriate changes.

14. Click the “Control” tab.

By default, a new Processor Configuration will not automatically run when the service starts (“Runs on

Start”) nor will it run on a schedule (“Runs on Schedule”). For our purposes, we only need this Processor

Configuration to execute on start.

15. Change “Runs On Start” to “True”.

16. Click “Save”

Page 65: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 64 of 86

We can run our Processor Configuration manually now by clicking the “Start” button. To confirm the

Processor executed successfully perform the following.

1. Click the “EWS Servers” tab.

2. Confirm there is an entry with the name “SmartConnector Weather Service”.

3. Click the edit icon. You should see details similar to Figure 69

4. Navigate the tree from “Root ContainerItem” to confirm the infrastructure has been added.

5. Confirm that it is running (indicated by the presence of a “Stop” button).

Figure 69: Portal – EWS Server Detail Page

7.3 Add Configuration (UpdateProcessor)

We will now add a Processor Configuration for the UpdateProcessor.

1. From the Portal, click “Configurations-Processor”.

2. Click “Add New”.

3. Select “SmartConnector.WeatherExtension”

4. Click “Next”

5. Select “SmartConnector.WeatherExtension.UpdateProcessor”

6. Click “Next”

7. Click “Finish”

Page 66: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 65 of 86

8. Click the “Details” tab on the “Processor Configuration” page.

9. Click “Validate”. You should see a validation prompt displayed such as in Figure 70.

Figure 70: Portal – UpdateProcessor Configuration

10. Click the edit icon for the “Api Key” field.

11. Enter your developer API key for https://home.openweathermap.org which you obtained into

the “Api Key” input.

12. Edit “Update Current Conditions” to “True”

13. Edit “Update Forecast” to “True”

14. Click “Save”

15. Click “Validate”

To verify that the processor succeeded, navigate to the EWS Server shown in Figure 69. Explore the

“CurrentConditions” and “Forecast” ValueItem children and you should see values as shown in Figure

71 and Figure 72.

Page 67: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 66 of 86

Figure 71: Current Conditions Data

Figure 72: Forecast Data

Page 68: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 67 of 86

7.4 Verify Custom Server

One final step remains; to confirm the CustomSetValuesProcessor is setting “volatile” data to

Uncertain. In order to test this, we need to make a SOAP web-service call to our EWS endpoint. The

best choice for this is a free tool called SoapUI.

1. Open SoapUI

2. Create a new Project.

3. Right click the project folder and select “Add WSDL”. You should see a dialog like Figure 73.

Figure 73: SoapUI – Add WSDL

4. In the “WSDL Location” enter the WSDL “Address” of the EWS Server (e.g.

http://localhost:5300/SmartConnectorWeatherService?singleWSDL).

5. Click “OK”. You should see the list of supported methods as shown in Figure 74.

Page 69: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 68 of 86

Figure 74: SoapUI – SOAP Method List

6. Expand the “SetValues” node in the tree on the left.

7. Double click “Request 1”. SoapUI should show an empty request as shown in .

8. Click “Auth” tab at the bottom.

9. Select “Add New Authorization”

10. Choose “NTLM”

11. Enter the “Username” and “Password” for the EWS Server (e.g. admin/Admin!23 by default).

12. In the SetValuesRequest element, set the version attribute to “1.2”

13. In the ValueItem element, set the Id sub-element to “CityCode”

14. In the ValueItem element, set the Value sub-element to “6455259”. Your request should look

like Figure 75.

Page 70: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 69 of 86

Figure 75: SoapUI – SetValuesRequest

15. Click the green play button in the toolbar of the request.

16. The SOAP response from the server will be displayed at the right.

Using the Portal again, we can navigate back to our EWS Server and see that the “City Name” and “City

Code” values have been updated and that the “State” of each is “Uncertain” as shown in Figure 76.

Page 71: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 70 of 86

Figure 76: Portal – CityName and CityCode

Finally, we can go to the Processor Configurations page one last time and run the “Weather Update

Processor” again. If we then refresh the CityName and CityCode ValueItem we will see that our

mysterious CityCode value was for Paris. A list of all supported city codes is available here:

http://78.46.48.103/sample/city.list.json.gz

The realities of deploying to a real production environment are no different than what we have just

demonstrated. We probably would want our UpdateProcessor to run on a schedule; perhaps even

different schedules for “Current Conditions” and “Forecast” since the former is more likely to change

more frequently than the later.

8 Licensing Your Extension SmartConnector supports licensing for any portion of your Extension Assembly. If you as the

SmartConnector Developer wish to protect your intellectual property and/or derive revenue from the

sale of your SmartConnector based solution, licensing is a prudent endeavor.

SmartConnector licenses are created and managed entirely by you in your personal Tenant at

www.smartconnectorserver.com. Once generated, the license itself is immutable. Additionally, once a

license is added to the SmartConnector runtime, the data cannot be altered even though it is stored in

Page 72: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 71 of 86

the SmartConnector database. Any edits to either the physical file or the database license fields will

render the license unusable.

Licenses can be created with the following restrictions. Multiple restrictions will behave in a logical

“OR” fashion:

• Time based licensing. License will expire at an absolute date in the future.

• Machine based licensing. Licenses can be generated that allow code to run on only a specific

machine.

• Version based licensing. Licenses can be generated that will only allow specific versions of the

extension assembly to execute.

• Licenses can be generated with custom features that are enforced at run time from the

Extension itself. See Custom Licensing for more details.

8.1 Create SmartConnectorServer Entries

Licensing is a two-step process. The first step involves generating the necessary records on

www.smartconnectorserver.com: Extension, License Template, and a License. Once created, your

Extension Assembly requires minor modifications to associate it instruct the SmartConnector runtime on

how to enforce licensing.

As promised, we will now add licensing to our Extension Assembly.

8.1.1.1 Create Extension

The “Extension” we are creating here is a logical representation of your actual Extension Assembly.

1. Go to www.smartconnectorserver.com and login with your choose authentication provider.

2. Click the “Extensions” tab

3. Click “Add New”

4. Enter a “Name”. Names should be considered public facing so you should create a description

one. For our Extension Assembly, we will enter “SmartConnector Sample WeatherExtension”

5. Enter an optional “Description”. Descriptions are for your internal use and can contain any

information deemed pertinent.

6. Enter the “Assembly Name”. The assembly name is the actual Extension Assembly file name.

For our Extension Assembly we will enter “SmartConnector.WeatherExtension.dll”.

7. Enter the “Assembly Id”. This field is critical. This value must be the Guid value in your

Extension Assembly’s “AssemblyInformation” file. This value must be unique within

SmartConnectorServer. This prevents another SmartConnector Developer from creating

fraudulent licenses for your assemblies.

8. Click “Save”. The page should look like Figure 77.

Page 73: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 72 of 86

Figure 77: SmartConnectorServer – Extension Page

You will notice some new fields that were not on the ‘new’ page; specifically the “Public Key” field. This

is one half of a public/private key pair that SmartConnectorServer uses to create license files. We will

use this Public Key shortly to update our Extension Assembly.

8.1.1.2 Create LicenseTemplate

For each logical “Extension”, you can create any number of different “License Template” instances. A

License Template defines how individual Licenses files will be generated. For example, you could create

a License Template which only allows use to anyone for 30 days (i.e. a demo license) or you could create

one with no expiration, but it only works on a specific physical machine (i.e. a machine thumbprint is

required).

In order to create an actual License, we’ll first need to create License Template.

1. From the Extension Detail page shown in Figure 77, click “New License Template”

2. Enter a “Name”. Names are public facing and should be short by descriptive (e.g.

“SmartConnector Weather Extension DEMO”).

3. Enter an optional “Description”. Descriptions are for your internal use and can contain any

information deemed pertinent.

4. Assembly Version is optional. If used, the License Template would be associated with a specific

version of your code. Wild carding is supported here. Enter in “1.0.*” which translates major

version 1, minor version 0, revision any.

5. Click “Save”. The page should look like Figure 78.

Page 74: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 73 of 86

Figure 78: SmartConnectorServer – License Template Page

8.1.1.3 Create License

For each logical “License Template”, any number of different “License” instances can be created. A

License is the actual immutable license which you will provide to consumers.

1. From the License Template Detail page shown in Figure 78, click “New License”

2. Enter a “Name”. Names represent the actual file name which is generated (e.g.

“SmartConnector.WeatherExtension.lic”). Use of “.lic” or no extension has not appreciable

value. We use “.lic” here out of convention.

3. Enter an optional “Description”. Descriptions are for your internal use and can contain any

information deemed pertinent.

4. Click “Save”. The page should look like Figure 79.

5. Click the “Download License” button.

Page 75: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 74 of 86

Figure 79: SmartConnectorServer – License Page

There it is. We have created a license. Unfortunately, by not providing an Expires value or requiring a

Thumbprint, anyone with access to the license file we just downloaded would be able to use it. This is

certainly not a practical option for a real world Extension.

Luckily, www.SmartConnectorServer.com supports more intelligent and scalable workflows then the

“Manual license creation” workflow demonstrated here. Please review the FAQ page on that site.

Additional questions can be brought up in the SmartConnector Developer Forum. Also, review Custom

Licensing on how to add and enforce custom licensing into your Extension Assembly.

8.2 Update Extension Assembly

Now that we have created the infrastructure to support licensing we need to update our Extension

Assembly so that it can report to the SmartConnector runtime that a license file is required.

1. Open up the AssemblyInfo.cs file in the root of your class library project. This is the same file we

annotated earlier.

2. Locate the [assembly: AssemblyCulture("")] line.

3. Add a custom assembly attribute on the next row as shown in Figure 80.

4. Paste in the PublicKey value from the www.smartconnectorserver.com Extension created

earlier.

Page 76: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 75 of 86

Figure 80: AssemblyInfo file with PublicKey

8.3 Enable Licensing at the Processor

The prior step only allows SmartConnector to perform license enforcement on any licensable item in the

Extension Assembly. If we stopped now, nothing would really have changed as all of the code we have

written so far included an IsLicensed which returned false. To prevent any of that code from executing,

we simply need to update the appropriate lines of code to return true.

1. Open WeatherProcessorBase

2. Locate the IsLicensed override.

3. Comment out or delete the override.

4. Rebuild the solution.

We now have licensing. Let’s test it out.

8.4 Updating Extension Assemblies

Updating Extension assemblies after initial deployment is performed in the same manner as initial

deployment. If the Extension being updated was being used, the .NET framework will put a file lock on

the DLL which will prevent it from being overwritten. While workarounds are being considered,

presently you will need to stop the SmartConnector service prior to updating your Extension assemblies.

After updating your deployed Extension Assembly and restarting the SmartConnector service we can

verify our licensing requirements.

1. From the Portal, click “Configurations-Processor”.

2. Click the edit icon for either Processor Configuration.

3. Click “Validate”. You will notice a “No license found” prompt.

4. Click “Setup-Licenses”

5. Click “Add”

6. Browse to the location of the license file we downloaded earlier.

7. Click “Open”

8. Repeat steps 1-3. Validation is successful!

Page 77: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 76 of 86

9 Appendix

9.1 Strong-Named Assemblies

All SmartConnector binaries are Strong-Named Assemblies. All Extension assemblies must be compiled

with the NuGet packages corresponding to the version of the SmartConnector runtime to which it will

be deployed, unless otherwise specified by the release notes of the runtime version in which you are

using. Failure to do this will result in a runtime exception when the SmartConnector framework

attempts to load an assembly.

This requirement is true regardless of whether or not you strongly name your Extension assembly or

whether or not you incorporate licensing requirements into your Extension assembly.

See the Troubleshooting section in the SmartConnector Installation and Configuration Guide for more

details.

9.2 NuGet Packages

SmartConnector provides several NuGet packages to facilitate Extension development and testing. All

public NuGet packages are summarized below with a brief description as to their scope. More details on

the functionality available in each sections below.

9.2.1.1 SxL.Common

This NuGet package contains low level support classes for other packages.

9.2.1.2 SxL.Licensing

This NuGet package contains helpers for licensing aspects.

9.2.1.3 Ews.Common

This NuGet package contains EWS data constructs which are commonly used when serving EWS or

consuming a EWS endpoint.

9.2.1.4 Ews.Client

This NuGet package contains all classes and data proxy constructs needed to consume any EWS v1.1 or

EWS 1.2 compliant endpoint.

9.2.1.5 Ews.Server.Contract

This NuGet package contains a fully customizable MVC style EWS Server implementation.

9.2.1.6 Ews.RestExtensions

This NuGet package contains a fully customizable MVC style RESTful implementation based on an EWS

like data model.

9.2.1.7 Mongoose.Common

This NuGet package contains low level support classes for the SmartConnector Runtime.

Page 78: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 77 of 86

9.2.1.8 Mongoose.Configuration

This NuGet package contains data classes for creating SmartConnector Processor Configurations.

9.2.1.9 Mongoose.Csp

This NuGet package contains all classes and data constructs to interactive natively with EcoStruxure

Buildings Operations servers (AS or ES) using the native CSP protocol. License Required.

9.2.1.10 Mongoose.Ews.Server

This NuGet package contains the SmartConnector standard EWS Server implementation. It can be

customized as needed.

9.2.1.11 Mongose.Ews.Server.Data

This NuGet package contains classes for managing the internal data for a SmartConnector EWS Server.

9.2.1.12 Mongoose.Ews.Server.Sample

This NuGet package contains classes which illustrate how to extend and consume SmartConnector EWS

Servers. This package will be reviewed in detail in a later section.

9.2.1.13 Mongoose.Process

This NuGet package contains the core SmartConnector framework library. When creating custom

Processors, you will always need to include this NuGet package.

9.2.1.14 Mongoose.Process.Sample

This NuGet package contains classes which illustrate how to extend and consume SmartConnector

Processors. This package will be reviewed in detail in a later section.

9.2.1.15 Mongoose.Test

This NuGet package contains classes, extension methods and other helpers to aid in writing unit tests for

Processors.

9.3 SmartConnector Interfaces

The following is a list of some of the more common and widely used interfaces found in the

SmartConnector libraries.

9.3.1 ITraversable

Any class decorated as ITraverseable will allow graph traversal by the ObjectExaminer class for deep

analysis. This is specifically used for Validation and to extract configuration information from a

Processor or REST Endpoint. If a reference type property is added to a Processor which will require

exposure via the configuration engine, you need to decorate those classes with this interface so that

child properties will be exposed.

9.3.2 ILongRunningProcess

A Processer should perform its work as efficiently as possible and terminate. This will allow the finite

number of Workers available to be reused as other Processors need to be executed. It is understood

that sometimes a Processor can’t be written in such a manner. For example, if the processor is

Page 79: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 78 of 86

communicating with a third party system by opening a socket and “listening” for traffic it may need to

do so for an indefinite amount of time before exiting.

For cases like this, the interface ILongRunningProcess should be used to assure the SmartConnector

Runtime that the Processor has not become unresponsive or stuck in an infinite loop. Failure to do so

may cause the Worker Manager to terminate the Process because it has become unresponsive.

9.3.3 IEndpoint

The IEndpoint defines the properties needed to connect to any HTTP endpoint (including an EWS

Server). Extension methods exist to instantiate an EwsClient instance based on the credentials of an

implementing class. SmartConnector’s native EWS readers and writers implement this interface.

9.3.4 IStaThreadedProcessor

If a Processor contains references to COM assemblies the Processor may be required to execute in an

STA thread. To instruct the Worker Manager to handle threading using STA threads, the author should

include the sub-class directive for this interface.

9.4 SmartConnector Attributes

The following is a list of some of the more common and widely used attributes found in the

SmartConnector libraries.

9.4.1 CollectionLengthAttribute

Found in the Mongoose.Common.Attributes namespace, this attribute specifies the minimum and/or

maximum number of items that can be in any IEnumerable.

9.4.2 ConfigurationDefaultsAttribute

Found in the Mongoose.Common.Attributes namespace. When attributed to a Processor sub-class, a

newly created ProcessConfiguration or EndpointConfiguration will automatically populate the

Name and Description with the supplied values.

9.4.3 ConfigurationIgnoreAttribute

Found in the Mongoose.Common.Attributes namespace. Processor properties with this attribute will be

ignored by SmartConnector for the purposes of configuration and will not be displayed to the user in the

Portal.

9.4.4 EncryptedStringAttribute

Found in the Mongoose.Common.Attributes namespace. Configuration properties derived from items

with this attribute will be encrypted when they are written to the SmartConnector database and

decrypted when they are read from the database.

9.4.5 NotTraverseableAttribute

Found in the Mongoose.Common.Attributes namespace. Processor reference type properties with this

attribute will be considered NOT traversable when it would otherwise be traversable (e.g.

ITraversable or IEnumerable).

Page 80: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 79 of 86

9.4.6 RandomStringDefaultValueAttribute

Found in the Mongoose.Common.Attributes namespace. SmartConnector includes a sub-class of the

System.ComponentModel.DefaultValueAttribute which will generate a random string value rather

than one the extension author defines.

9.4.7 TooltipAttribute

Found in the Mongoose.Common.Attributes namespace. A Processor author can decorate any

configurable property with the Tooltip attribute. The contents of the “tip” will be rendered in the

SmartConnector Portal when the user clicks on the icon. This can be useful to provide context based

instructions and guidance to Portal users.

9.4.8 VisibleWhenAttribute

Found in the Mongoose.Common.Attributes namespace. A Processor/Endpoint author can decorate

any configurable property with the VisibleWhen attribute. This attribute specifies a property and an

array of values that the value of property must be for this property to be visible to the user while

viewing the configuration in the portal. A configuration property can be decorated with multiple

VisibleWhen attributes. Doing so will result in a logical OR for determining visibility.

9.5 EwsServerDataAdapter

Managing native SmartConnector EWS Server data and the data relationships is done with the

EwsServerDataAdapter class. This class provides access and full CRUD capabilities to all aspects of native

SmartConnector EWS Servers.

See Mongoose.Ews.Server.Data.EwsServerDataAdapter for a comprehensive list of supported

methods and properties.

9.6 Custom Licensing

Custom license features can be used to provide highly granular control of specific aspects of an

Extension. Custom license features are represented as a Dictionary of string values. For the majority of

scenarios, this should suffice. However, if more complicated design scenarios are required, you can

store a serialized object in the value and deserialize it at runtime.

Enforcement of the custom licensing features is the responsibility of the Extension author. This

enforcement is accomplished by overriding the ValidateCustomLicenseFeatures method and

returning the appropriate Prompt instance in the response. An example for the

LicensedNullProcessor is shown in Figure 81 below.

The custom license feature in this example is called “MaxSleep” and represents the maximum allowed

sleep value which the Processor can be configured for. By deferring this validation from design time

(using attribute validation) to runtime, different customers can operate the same Processor under

different constraints.

Page 81: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 80 of 86

Figure 81: ValidateCustomLicenseFeatures Override

9.7 Sharing Data within SmartConnector

When solutions require data to be shared across Processors, EWS SOAP Processors, or EWS REST

Controllers, there are two options available: in-memory cache or ProcessorValue.

9.7.1 In-Memory Cache

The in-memory cache is a volatile (all data is lost on a service restart), thread safe approach to storing

value type or reference type data. Once added to the cache, any thread in the SmartConnector

execution environment can access this data. The actual references for reference type data do not

persist through the cache as all data is XML serialized inbound and deserialized outbound. Cached data

can be segregated into logical silos or “tenants” with optional expiration times for the data.

Access to the in-memory cache is done via a dependency injected instance of the ICache interface. See

Figure 82.

Page 82: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 81 of 86

Figure 82: InMemoryCache Example

9.7.2 Processor Values

A ProcessorValue is a reference type which can be saved to the database. By using a dependency

injected instance of the IProcessorValueDataSouce (optionally with an IProcessorValueHelper

interface), developers can easily have full CRUD capabilities on these items. While values are always

stored as string, reference types can be serialized prior to storing.

Processor and all EWS Server Processor base classes implement IProcessorValueHelper. See Figure

83.

Figure 83: IProcessorValueDataSource with IProcessorValueHelper Example

9.8 Managed Clients

The EwsClient class is used to create and hold open a connection to an EWS Server. Since EwsClient is

IDisposable, it is appropriate to dispose of references when done using them. Doing so terminates and

closes the connection. Unfortunately, some EWS Servers have only a limited pool of connections and

using dispose too often can deplete them.

Page 83: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 82 of 86

SmartConnector provides a managed pool of EwsClient connections which works around this issue.

Access to the pool is done via a dependency injected instance of the IManagedEwsClient interface. See

Figure 84 for an example.

Figure 84: IManagedEwsClient Example

Similarly, the CspClient can also be run in a “managed” fashion using the IManagedCspClient

interface. Instantiation of this interface is performed in the same manner as the IEwsClient and is

shown in Figure 85 below.

Figure 85: IManagedCspClient Example

9.9 Coordinating Actions

From time to time, circumstances may arise in your Extension development where one Processor needs

to spawn another. SmartConnector supports this functionality via a dependency injected instance of the

IActionBroker interface. Additionally, all Processor and EWS Server Processor sub-classes have an

ActionBroker property available to them. See Figure 86 for an example.

See Mongoose.Common.IActionBroker interface for available properties and methods.

Page 84: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 83 of 86

Figure 86: ActionBroker Example

9.10 Logging

SmartConnector extensively logs all activity. The Portal and SmartConnector Service log every request

and response in addition to all errors. Additionally, this NLog based logging framework is available to all

extension developers so they too can log to the same location.

What gets logged is determined by a combination of the global Logging Level Service Setting and Logging

Filters as described above.

All SmartConnector logs are written to the “%PROGRAMDATA%\SmartConnector\Logs” folder.

Page 85: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 84 of 86

See SxL.Common.Logger class for available methods.

See SmartConnector Installation and Configuration Guide on how to configure SmartConnector logging.

9.11 Third Party Tools

9.11.1 SoapUI

SoapUI is a free and open-source application available at http://www.soapui.org/. By creating queries

the can be used to test EWS Server endpoints, SoapUI is helpful for verifying passwords, validating

object IDs, and confirming proper SOAP formatting.

The process for using SoapUI is as follows:

• Create a new project referencing the EWS Server’s WSDL file (insert the actual endpoint exactly

as shown in EWS Server Detail Page.

• http://localhost:57621/DataExchange?singleWsdl

Select the Create Requests option to generate base queries for each EWS method available for your

EWS Server as shown in Figure 87.

Figure 87: SoapUI New Project

Page 86: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 85 of 86

9.11.2 Fiddler

Fiddler can be downloaded for free from http://www.telerik.com/download/fiddler. Fiddler is a web

debugging proxy which allows you to view the HTTP communication between any two endpoints.

Additionally, you can “fiddle” with the request and even create your own requests using the Composer.

Error! Reference source not found. shows the communication between SoapUI and the sample S

martConnector EWS Server establishing connectivity (WSDL request) and then the HTTP Digest

Authentication used to GetWebServiceInformation.

Figure 88: Fiddler Web Debug Proxy

9.12 Supported Operating Systems

The following is a list of Operating Systems which SmartConnector has been tested against. Non-listed

operating systems capable of running .NET 4.5 should also work but their compatibility has not been

verified.

• Windows 7 64 bit.

• Windows 10 64 bit.

• Windows Server 2008 64 bit.

• Windows Server 2012 64 bit.

• Windows Server 2016 64 bit.

9.13 Supported Database Servers

The following is a list of Microsoft SQL Servers which SmartConnector has been tested against. Non-

listed servers compliant with Microsoft SQL Server may also work but their compatibility is not

guaranteed.

• Local DB.

Page 87: SmartConnector Developers Guide · 2019. 4. 4. · SmartConnector Developers Guide Document : Revision Revision date Page TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page

SmartConnector Developers Guide

Document : Revision Revision date Page

TDS-M-DEVGUIDE-US.BU.N.EN.12.2017.2.30.CC 6 8/14/2018 Page 86 of 86

• Microsoft SQL Server 2012 Express.

• Microsoft SQL Server 2012.

• Microsoft SQL Server 2014 Express.

• Microsoft SQL Server 2014.

• Microsoft SQL Server 2016 Express.

• Microsoft SQL Server 2016.