SO-Aware Webinar on September 28, 2010

Hey Everyone,

For all those using SO-Aware as a replacement for UDDI, web service discovery and WSDL organization, we have a free webinar that you can view to see all about using SO-Aware for BizTalk Governance. Please check it out if you have a chance. ( http://www.regonline.com/register/checkin.aspx?EventId=894912 )

For those that don’t know what SO-Aware is, simply put, it is a Web Service Metadata Repository which supports WCF, ASMX, SOAP, JAVA, REST , and OData services. You can read more about it here: (http://www.tellagostudios.com/products/so-aware%E2%84%A2″).

Web Service Discovery in SO-Aware (Part 2)

In my last post we discussed what was Web Service Discovery, and how it’s two design patterns provide us with different implementations, such as UDDI, SO-Aware, and WCF 4.0 Discovery. In this post we will discuss WCF 4.0 Discovery, and how SO-Aware handles the two modes of WCF Discovery.

How Discovery works today

WS-Discovery provides a protocol to discover services that are coming into and leaving from a network. As a service joins the network, it informs its peers of its arrival by broadcasting a Hello message; likewise, when services drop off the network they multicast a Bye message. WS-Discovery doesn’t rely on a single node to host information about all available services as UDDI and SO-Aware. Which SO-Aware alleviates this for WCF registered services by downloading a cached copy of the configuration to the WCF Service, such that the WCF Service Host retrieves it’s setting from the cached copy if SO-Aware is down. Rather, for WS-Discover each node forwards information about available services in two ways, an ad hoc fashion or a managed mode. This reduces the amount of network infrastructure needed to discover services and facilitates bootstrapping. My Business partner, Jesus Rodriguez has an excellent blog posting on WS-Discover with WCF 4.0. When using WS-Discovery with WCF 4.0, we can use the SO-Aware Service Repository as both the ad hoc and managed mode implementation.

How SO-Aware Handles WCF 4.0 Discovery ad hoc mode

Using WCF 4.0 Discovery requires running the SO-Aware Web Site and ServiceRepository service with .Net 4.0. You can tell ASP.NET to dymanically recompile the web site and data service to use the .Net 4.0 framework. Follow the steps outlined in this post (http://tellagostudios.com/how-setup-so-aware-run-net-40) to do this.

Next is to turn on WCF Add Hoc Discovery in the Service Host. The Current SO-Aware Service Repository host uses the default WCF DataService Service host. By Default this host does not know anything about the discovery mechanism. Thus I have created a new Service Host Factory which injects details about the discovery mechanism. This host is named: Tellago.ServiceModel.Governance.Data.DataServiceHostFactory, which derives from the default WCF DataServiceHost, and adds the Discovery behavior, Annoucement and Discovery Endpoints to the DataServiceHost, making it support the WCF 4.0 Discovery mechanism. Open the ServiceRepository.svc markup with a text editor, and change it’s Factory to point to the new DataServiceHostFactory as such:

Factory = "Tellago.ServiceModel.Governance.Data.DataServiceHostFactory, Tellago.ServiceModel.Governance.Data"

Look for the Tellago.ServiceModel.Governance.Data project inside the SDK folder (\Samples\.Net40\WCF Discover) and compile the project. Copy the resulting dll into the bin directory of the SO-Aware web site, run the site, and now you have Ad hoc discovery mechanisms. The ability to add a service version for (OData, REST, or Soap) and remove a service version entry generates "Online" and "Offline" announcement broadcasts to all listening announcement endpoint clients. (Note: this example only works when the client announcement endpoints are on the same subnet as the SO-Aware ServcieRepository service) It also uses the managed mode approach by creating a Discoverable Host and proxy which clients can use to listen for these announcements. I stress, this is sample code only as it shows how to implement such a thing with SO-Aware.

The way the custom ServiceHost Factory works is by injecting a WCF Message Inspector into the DataServiceHost. The Message Inspector parses the DataService message contents. You know, a funny thing about WCF Data Services is that, the message content is sent and received in a binary, base64 encoded, multi-part message format. Basically it’s a batch message of Xml, post/merge/put/delete messages all delimited by "\r\n\r\n—changeset_{guid}". This was not fun to parse let me tell you. In anycase the inspector looks within the Batch message for the Xml contents, Post method verb in the message properties, and a term="" the entity type in question. If the Entity type is "ServiceVersion" and the Post contains an term="restdescription" or "odatadescription" or "soapdescription" then I know the insert or update message is a Service Version. Upon "Offline" broadcasts, the message inspector looks for a Http Delete verb method in the message properties of the batch and looks for a "ServiceVersion" term as well as the "restdescription", "odatadescription" and "soapdescription" entity names (loweredcased…) to determine if it should broadcast "Offline" messages to announcement endpoints.

To create a client application that uses the Ad Hoc discovery service is rather simple. First you create a DiscoveryClient instance, and add a UdpDiscoveryEndpoint instance to its constructor. The UdpDiscoveryEndpoint already contains a hardcoded Uri which points so some standard urn:docs-oasis-open-org:ws-dd:ns:discovery:2009:01
address version, believe it or not, this is a valid Uri address. Once the discovery client is created, create event handlers to listen for when the Discovery Client has completed it Find operation. Start or invoke the Find operation by using the FindAsync() method of the Discovery Client and wait for the responses, you’re done.

Here’s a code example:

   1: class Program

   2: {

   3:     static DiscoveryClient client;

   4:     static AnnouncementService svc = new AnnouncementService();

   5:     static ServiceHost announcementHost = null;

   6:  

   7:     static void Main(string[] args)

   8:     {

   9:         client = new DiscoveryClient(new UdpDiscoveryEndpoint());

  10:         client.FindProgressChanged += new EventHandler<FindProgressChangedEventArgs>(client_FindProgressChanged);

  11:  

  12:         client.FindCompleted += new EventHandler<FindCompletedEventArgs>(client_FindCompleted);

  13:         client.FindAsync(new FindCriteria(typeof(ServiceRepositoryDataService)));

  14:        

  15:  

  16:         announcementHost = new ServiceHost(svc);

  17:         announcementHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());

  18:         svc.OnlineAnnouncementReceived += new EventHandler<AnnouncementEventArgs>(svc_OnlineAnnouncementReceived); svc.OfflineAnnouncementReceived += new EventHandler<AnnouncementEventArgs>(svc_OfflineAnnouncementReceived);

  19:        

  20:         announcementHost.BeginOpen((result) =>

  21:         {

  22:             announcementHost.EndOpen(result);

  23:         }, null);

  24:  

  25:         Console.WriteLine("Searching...\n");

  26:         Console.ReadLine();

  27:  

  28:     }

  29:  

  30:     static void svc_OfflineAnnouncementReceived(object sender, AnnouncementEventArgs e)

  31:     {

  32:         Console.WriteLine("Service went offline: {0} ", e.EndpointDiscoveryMetadata.Address );

  33:     }

  34:  

  35:     static void svc_OnlineAnnouncementReceived(object sender, AnnouncementEventArgs e)

  36:     {

  37:         Console.WriteLine("Service came online: {0} ", e.EndpointDiscoveryMetadata.Address );

  38:     }

  39:  

  40:     static void client_FindCompleted(object sender, FindCompletedEventArgs e)

  41:     {

  42:         if (e.Error == null)

  43:         {

  44:             if (e.Result.Endpoints.Count > 0)

  45:             {

  46:                 Console.WriteLine("Find Completed Ran\n{0}", e.Result.Endpoints[0].Address);                 

  47:             }

  48:             if (client.InnerChannel.State == System.ServiceModel.CommunicationState.Opened)

  49:             {

  50:                 client.Close();

  51:             }

  52:             Console.ReadLine();

  53:         }

  54:         else

  55:         {

  56:  

  57:             Console.WriteLine(e.Error.ToString());

  58:             Console.ReadLine();

  59:         }

  60:     }

  61:  

  62:     static void client_FindProgressChanged(object sender, FindProgressChangedEventArgs e)

  63:     {

  64:         Console.WriteLine("Percentage Complete:\n{0}%\n", e.ProgressPercentage.ToString());

  65:     }

  66: }

  67:  



How SO-Aware Handles WCF 4.0 Discovery in managed mode

One of the disadvantages to using Ad Hoc discovery is that all the clients must reside on the same subnet due to the UDP multicasting protocol. Managed mode Discovery, provides a way to discover services on other protocols besides the UDP multicast protocol. It works by way of a custom "Discoverable Proxy". The discoverable proxy can query for online services through discovery endpoints, or through any custom means. The concept is simple, a client/service interested in discovery first calls the discoverable proxy and asks it for registered services. The discoverable proxy then returns a list of "Online" services as announcements or some other transport mechanism. This is where SO-Aware can really shine. The SO-Aware Discoverable proxy uses the SO-Aware central repository to discover services being "Online" and "Offline".

The steps to use this discoverable proxy are simple, you can continue to use the announcement client endpoints, as long as they reside on the same subnet, and you can create a client that queries directly into the proxy using the address of the discoverable proxy. In this release, the address is hard coded to net.tcp://localhost:7777/discoverableproxy endpoint address. The next release, v2 of the SO-Aware implementation will allow you to take full advantage of the configuration and repository to control which binding and what uri listening address.

The way the SO-Aware discoverable proxy works is by creating a class that derives from the DiscoveryProxy base abstract class. This class allows you to implement four asynchronous paired (Beginxx and Endxx) methods, OnBeginOnlineAnnouncement, OnBeginResolve, OnBeginFind, OnBeginOfflineAnnoucement

Here’s a sample OnBeginFind method example:

   1:  

   2:      protected override IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state)

   3:      {            List<EndpointDiscoveryMetadata > services = new List<EndpointDiscoveryMetadata>();

   4:          var ctxt = new ResourceRepositoryContext(this.ServiceRepositoryUri);

   5:          ctxt.Credentials = System.Net.CredentialCache.DefaultCredentials;

   6:  

   7:          var Soaps = from sp in ctxt.SoapDescriptions.Expand("ServiceVersion")

   8:                      select sp;

   9:          foreach (var soapDescription in Soaps)

  10:          {                

  11:              foreach (var ep in soapDescription.Endpoints )

  12:              {

  13:                  EndpointDiscoveryMetadata discovery = new EndpointDiscoveryMetadata();    

  14:                  discovery.Address = new EndpointAddress(ep.Address );

  15:                  discovery.Extensions.Add(XElement.Parse(String.Format("<ServiceVersionName>{0}</ServiceVersionName>", soapDescription.ServiceVersion.Name)));

  16:                  services.Add(discovery );                    

  17:              }

  18:          }

  19:          var odatas = from od in ctxt.ODataDescriptions.Expand("ServiceVersion")

  20:                       select od;

  21:          foreach (var oDataDescription in odatas)

  22:          {

  23:              EndpointDiscoveryMetadata discovery = new EndpointDiscoveryMetadata();

  24:              discovery.Address = new EndpointAddress(oDataDescription.MetadataURI );

  25:              discovery.Extensions.Add(XElement.Parse(String.Format("<ServiceVersionName>{0}</ServiceVersionName>", oDataDescription.ServiceVersion.Name)));

  26:              services.Add(discovery);

  27:          }

  28:          var rests = from rs in ctxt.RestDescriptions.Expand("ServiceVersion")

  29:                      select rs;

  30:          foreach (var restDescription in rests)

  31:          {

  32:              EndpointDiscoveryMetadata discovery = new EndpointDiscoveryMetadata();

  33:              discovery.Address = new EndpointAddress(restDescription.BaseURI );

  34:              discovery.Extensions.Add(XElement.Parse(String.Format("<ServiceVersionName>{0}</ServiceVersionName>", restDescription.ServiceVersion.Name)));

  35:              services.Add(discovery);

  36:          }

  37:          var query = from service in services

  38:                      where findRequestContext.Criteria.IsMatch(service)

  39:                      select service;

  40:  

  41:          var queryCache = from service in cache

  42:                           where findRequestContext.Criteria.IsMatch(service)

  43:                           select service;

  44:  

  45:          foreach (var metadata in query)

  46:          {

  47:              findRequestContext.AddMatchingEndpoint(metadata);

  48:          }

  49:  

  50:          foreach (var endpointDiscoveryMetadata in queryCache)

  51:          {

  52:              findRequestContext.AddMatchingEndpoint(endpointDiscoveryMetadata );

  53:          }

  54:          return new OnFindAsyncResult(callback, state);          

  55:  

  56:      }



Briefly let’s talk about each of the 4 asynchronous methods, if you want details, MSDN is the best resource for that. The names are self explanatory. BeginFind allows you to lookup services when you find them you just call the findRequestContext.AddMatchingEndpoint(). This method announces to the clients a service has be found immediately. The BeginOnlineAnnouncement and BeginOfflineAnnouncement methods are there for you to cache them for clients calling into your proxy for this information. And lastly BeginResolve allows you to query your cache or in our case the SO-Aware ServiceRepository for service versions to return an Endpoint Address and Service Version Metadata.

To create a client application that uses this managed mode design is also simple. First you create a DiscoveryEndpoint instance and use the same binding and endpoint address of the discoverable proxy you are communicating with. In the case of SO-Aware, it’s binding is a NetTcpBinding with all the default settings, with the endpoint address set to: net.tcp://localhost:7777/discoverableproxy. After you create the DiscoveryClient, you can add the events are mentioned earlier (FindProgressChanged, FindCompleted) to listen for the "Online" and "Offline" messages. To start the process you invoke the FindAsync() method accordingly

Here’s a code example:

   1: Console.WriteLine("Now using Managed proxy on net.tcp://localhost:7777/discoverableproxy");

   2:  

   3: DiscoveryEndpoint ept = new DiscoveryEndpoint(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:7777/discoverableproxy"));

   4:  

   5: client = new DiscoveryClient(ept);

   6:  

   7: client.FindProgressChanged += new EventHandler<FindProgressChangedEventArgs>(client_FindProgressChanged);

   8:  

   9: client.FindCompleted += new EventHandler<FindCompletedEventArgs>(client_FindCompleted);

  10:  

  11: client.FindAsync(new FindCriteria(typeof(ServiceRepositoryDataService)));

  12:  

  13: Console.ReadLine();

  14:  



Putting it all together: Summary

Once you take advantage of the WCF 4.0 ws-discovery mechanisms you can have clients listen for registered services, such that when service versions are registered with SO-Aware, a client can immediately be notified the service metadata is now in SO-Aware. In the upcoming version, the Service "Online" and "Offline" announcement features will be more exact and technically correct. We will do this by actually checking if the registered Service is truly online. SO-Aware can do this through it’s pinging mechanism, which is included in the current version of SO-Aware. It’s the "Supports Is Alive" option in SO-Aware. We’ll talk more about this option in another posting.

Figure 1 SO-Aware Pinging Mechanism – Supports Is Alive

So, to make a long story short, there are a ton of possibilities here. SO-Aware can integrate into WMI, and SCOM to provide for a realtime monitoring of services going "Online" and "Offline". SQL Reporting mechanisms can be built to monitor who adds service versions, who takes them offline, and other things. Sharepoint can be used and cataloged itself using it’s REST based services. Mobile devices can have clients created that go through SO-Aware to retrieve its configuration and all be notified when new services are available to take advantage of them.

You need to Become SO-AWARE!!!

Take a look at some of the screen shots:

Figure 2 Client Using Broadcast Ad Hoc Discovery

Figure 3 Client Using Managed Mode Discover through SO-Aware

Figure 4 Adding and Removing Service Versions in SO-Aware

SO-Aware SDK Samples and Utilities

Just uploaded a refresh of SO-Aware SDK Samples and Utilities:

SDK Samples Include:

  • People Finder WCF Service Custom Service Host Factory Sample
  • Client Configurable Proxy Factory Sample
  • Client Configuration Resolver Sample
  • Unit Tests
  • Silverlight  & REST WCF Services Sample
  • People Finder WCF Service
  • BizTalk ESB SO-Aware Resolver Sample

Utility Includes:

  • PowerShell Provider (Over 35 Commandlets)

You can get the refresh here: http://tellagostudios.com/resources/so-aware-sdk-samples-and-utilities

For the BizTalk Enthusiasts, you can read about how to use the SO-Aware ESB Resolver here:

http://tellagostudios.com/so-aware-esb-resolver-microsoft-biztalk-sever

Web Service discovery in SO-Aware (part 1)

Introduction

Web services have been around for over 10 years now in some form or fashion. What this means is that there are millions of services in existence, on the public internet as well as your private network, and they mostly all lack at least one thing in common, discovery. Discovery is the mechanism by which web services and clients can be made aware of other web services and clients on a network. Discovery comes in two basic designs. One design pattern is where a client or service queries a central repository for registered services to find and discover details about it. Another design pattern is based on broadcasting and notification, where a special protocol is used to announce a client or service’s joining and leaving the network.

When developing web services with the Microsoft technology stack, Microsoft first introduced the Soap toolkit. Afterwards, ASP.NET ASMX was created to quickly build web services, following that the WSE extensions, and finally as its most current technology Windows Communication Foundation with version 4.0 of the .Net 4.0 Framework. WCF and .Net 4.0 Framework brings some interesting new features to the table, one in particular deals with web service Discovery using the WS-Discovery standard. This new standard takes the broadcasting and announcement design pattern to discovery.

How Discovery Worked Prior to Today

Prior to this version of WCF, the only supported discovery mechanism, was the querying of a central repository, usually UDDI sometimes through a class called the Metadata Resolver, but mostly through the UDDI API classes and methods. UDDI provided a central registry to store information about available services. It supplied a catalog where clients and services could find services that meet their needs. It is more similar to a yellow-page phonebook directory of information allowing the client or service to find other services by name, address, contract, category, or by other metadata. UDDI can be thought of as a very poor implementation of DNS for Web services.

Needless to say, the UDDI API stack never really made headlines. The reason being the API was far too complex, and it’s development model was too clunky to fit the Web Service executing platform, and no-one except the inventors of UDDI, understood tModels especially if all you wanted was a url to a service named “OrdersService”. What I mean by this is that Web Services were based off the HTTP protocol, with SOAP additions in a stateless model. While UDDI was created on the HTTP protocol, and using SOAP, UDDI implementations were too clunky and dealt more with the Business, and business model than with the actual service to really make an impact on the web service technology space. For example, to retrieve the details you were looking for, you needed to create multiple tModels, tModelRequests and parse through multiple tModelResponses just to get to the specific information being requested, instead of “1 simple query call, that’s all.”

I digress, a little. There was nothing wrong with the query Design pattern, just the UDDI implementation. We at Tellago Studios, believe that the query design pattern has its benefits as long as the implementation follows more of a web service, SOA centric perception of a central repository. SO-Aware does just that. It provides a SOA Centric RESTful implementation to query a central repository. If you want the Url of a registered service, just query it using OData. However, SO-Aware doesn’t stop there. Because of it’s RESTful implementation, I will show in this two part article posting how SO-Aware can also take advantage of both the querying and the second design pattern: broadcast and announcements, using the WS-Discovery protocol and WCF 4.0.  Part 1 of this article continues to talk about querying a central repository, whereas part two discusses WCF 4.0 and the WS-Discovery mechanism and how SO-Aware can be leveraged with it. (Read Part 2 here)

How SO-Aware Handles Querying the SO-Aware Service Repository

Let’s first tackle the first design pattern for discovery, which is querying a central repository. SO-Aware provides its own Service metadata Repository, and contains a set of classes for both a Client and Service to use for querying it, as well as the core WCF Data Service: SO-Aware Service Repository which uses the OData protocol to query directly. (To see more information on these classes and the core Service Repository view our videos on Server Side API parts 1 and 2 along with the Client Side API parts 1 and 2). To keep in tune with the querying the central repository, I’ll focus on the client side classes for this post and handle the server side querying in another post.

To query the central repository on the client SO-Aware provides two classes, ConfigurableProxyFactory and ConfigurationResolver. These classes can be found inside the Tellago.ServiceModel.Governance.ServiceConfiguraion.dll assembly.

To borrow from the documentation: The ConfigurableProxyFactory class is used to configure a client proxy for communicating with the SO-Aware Service Repository to retrieve configuration, behavior and binding information. It is meant to be used within client source code for dynamically resolving configuration information. Behind the scenes it uses the WCF ChannelFactory class to create WCF Communication objects through channels for sending and receiving queries and responses. The steps to use this class are simple:

  1. Create an instance of this class in the Client / Service application
  2. Inside the constructor set the SO-Aware Configuration query
  3. Create a WCF Channel based on the service contract interface expected for communication.
  4. Invoke your service operations, you’re done.

Here’s a code example:

ConfigurableProxyFactory<ISampleService> factory = new ConfigurableProxyFactory<ISampleService>(new Uri(http://localhost:8088/SO-Aware/ServiceRepository.svc “), “SampleService(1.0)”, null);

ISampleService service = factory.CreateProxy();

var response = service.DoOperation(dataToService);

Using the ConfigurationResolver class is just as simple. This class is used to manually resolve SO-Aware Service Repository Bindings, Endpoints, and Endpoint Behaviors. This class is meant to be used within a client or service source code for dynamically and manually resolving configuration information. The Steps to use this class are:

  1. Determine which WCF component is needed for communication: Binding, Endpoint, or Endpoint Behavior.
  2. Create an instance of the ConfiguationResolver class.
  3. Manually create any supporting WCF components for communication such as Addresses, Bindings, Endpoints and Contracts, depending on what components you already have.
  4. Invoke the ConfigurationResolver.Resolve*() methods to retrieve Bindings, Endpoint information such as EndpointAddress, Contracts, and Behaviors and let SO-Aware create the rest of the components for you.

Here’s a code example:

ConfigurationResolver resolver = new ConfigurationResolver(“http://localhost:8088/SO-Aware/ServiceRepository.svc&#8221;)

var binding = resolver.ResolveBinding(“wsHttpBinding_ISampleServiceBindingName”);

var endpoint = resolver.ResolveEndpoint(“wsHttpBinding_ISampleServiceEndpointName”);

var behavior = resolver.ResolveEndpointBehavior(“wsHttpBinding_ISampleServiceBehaviorName”);

SampleServiceClient proxy = new SampleServiceClient(binding, endpoint.Address, new DnsEndpointIdentity(“localhost”) );

var result = proxy.InvokeSomeOperation();

Well that’s all for now, in the next part, part two, I will go into details of How SO-Aware works with WCF 4.0 Discovery using ad hoc mode.

How to Setup SO-Aware to run on .Net 4.0

Steps

SO-Aware was created using the .Net 3.5 framework. To support WCF 4.0 we must tell the Web Server hosting SO-Aware to use ASP.Net 4.0, and tell ASP.NET to recompile the application using the.Net 4.0 assemblies. One of the nice features about ASP.NET is that it can dynamically recompile your web application upon startup. To set this up open IIS Manager and navigate to your Application pool that runs SO-Aware:

To do this Open IIS:

  1. First switch the application pool SO-Aware is running inside of to use .Net 4.0.

  2. Next install asp.net 4.0 into IIS if it’s not already done by navigating to a Command prompt as administrator navigate to this folder:
  3. C:\windows\Microsoft.NET\Framework64\v4.0.30128\
  4. Type in this line:

aspnet_regiis.exe -ir

  1. Lastly, change the web.config file to utilize the .Net 4.0 assemblies references by copying this web config file located below. (Remember to change the <connectionStrings> to point to the correct SQL Server or SQL Express databases, and the <appSettings>
    values to point to the correct SO-Aware ServiceRespository.svc and Tracking.svc urls:

<configuration>

<system.diagnostics>

<sharedListeners>

<add name=”EventLog” type=”System.Diagnostics.EventLogTraceListener” initializeData=”SO-Aware”>

</add>

</sharedListeners>

<sources>

<source name=”Tellago.ServiceModel.Governance.Monitoring” switchValue=”Warning, Error”>

<listeners>

<add name=”EventLog”/>

</listeners>

</source>

</sources>

</system.diagnostics>

<connectionStrings>

<add name=”ResourceRepositoryContext” connectionString=”metadata=res://*/ResourceRepository.csdl|res://*/ResourceRepository.ssdl|res://*/ResourceRepository.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=ServiceRepository;Integrated Security=SSPI;MultipleActiveResultSets=True&quot;” providerName=”System.Data.EntityClient”/>

<add name=”TrackingEntities” connectionString=”metadata=res://*/TrackingModel.csdl|res://*/TrackingModel.ssdl|res://*/TrackingModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=ServiceRepository;Integrated Security=SSPI;MultipleActiveResultSets=True&quot;” providerName=”System.Data.EntityClient”/>

</connectionStrings>

<appSettings>

<add key=”ResourceRepositoryUri” value=”http://localhost:8090/SO-Aware/ServiceRepository.svc“/>

<add key=”TrackingRepositoryUri” value=”http://localhost:8090/SO-Aware/TrackingData.svc“/>

<add key=”ChartImageHandler” value=”storage=memory;deleteAfterServicing=true;”/>

</appSettings>

<system.serviceModel>

<serviceHostingEnvironment aspNetCompatibilityEnabled=”true”/>

<services>

<service behaviorConfiguration=”tracking” name=”Tellago.ServiceModel.Governance.Monitoring.TrackingService”>

<endpoint address=”Tracking” binding=”netTcpBinding” bindingConfiguration=”tracking” contract=”Tellago.ServiceModel.Governance.Monitoring.ITrackingService”/>

</service>

<service name=”Tellago.ServiceModel.Governance.Monitoring.TrackingServiceWeb” behaviorConfiguration=”tracking”>

<endpoint address=”” binding=”webHttpBinding” bindingConfiguration=”trackingWeb” contract=”Tellago.ServiceModel.Governance.Monitoring.ITrackingServiceWeb” behaviorConfiguration=”trackingWeb”/>

</service>

</services>

<bindings>

<netTcpBinding>

<binding name=”tracking” maxBufferPoolSize=”524288″ maxBufferSize=”5242880″ maxReceivedMessageSize=”5242880″>

<readerQuotas maxStringContentLength=”5242880″/>

</binding>

</netTcpBinding>

<webHttpBinding>

<binding name=”trackingWeb” maxBufferPoolSize=”524288″ maxBufferSize=”5242880″ maxReceivedMessageSize=”5242880″>

<readerQuotas maxStringContentLength=”5242880″/>

<security mode=”TransportCredentialOnly”>

<transport clientCredentialType=”Windows”/>

</security>

</binding>

</webHttpBinding>

</bindings>

<behaviors>

<endpointBehaviors>

<behavior name=”trackingWeb”>

<webHttp/>

</behavior>

</endpointBehaviors>

<serviceBehaviors>

<behavior name=”tracking”>

<serviceThrottling maxConcurrentCalls=”16″ maxConcurrentSessions=”20″/>

<serviceMetadata httpGetEnabled=”false”/>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

<system.web>

<!–

Set compilation debug=”true” to insert debugging

symbols into the compiled page. Because this

affects performance, set this value to true only

during development.

–>

<compilation debug=”true” targetFramework=”4.0″>

<assemblies>

<add assembly=”System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>

<add assembly=”System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>

<add assembly=”System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>

<add assembly=”System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089″/>

<add assembly=”System.Data.Services.Client, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″/>

<add assembly=”WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″/></assemblies>

</compilation>

<!–

The <authentication> section enables configuration

of the security authentication mode used by

ASP.NET to identify an incoming user.

–>

<authentication mode=”Windows”/>

<identity impersonate=”true”/>

<authorization>

<deny users=”?”/>

</authorization>

<!–

The <customErrors> section enables configuration

of what to do if/when an unhandled error occurs

during the execution of a request. Specifically,

it enables developers to configure html error pages

to be displayed in place of a error stack trace.

<customErrors mode=”RemoteOnly” defaultRedirect=”GenericErrorPage.htm”>

<error statusCode=”403″ redirect=”NoAccess.htm” />

<error statusCode=”404″ redirect=”FileNotFound.htm” />

</customErrors>

–>

<pages controlRenderingCompatibilityVersion=”3.5″ clientIDMode=”AutoID”>

<controls>

<add tagPrefix=”asp” namespace=”System.Web.UI.DataVisualization.Charting” assembly=”System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″/>

</controls>

<namespaces>

<add namespace=”System.Web.Mvc”/>

<add namespace=”System.Web.Mvc.Ajax”/>

<add namespace=”System.Web.Mvc.Html”/>

<add namespace=”System.Web.Routing”/>

<add namespace=”System.Linq”/>

<add namespace=”System.Collections.Generic”/>

</namespaces>

</pages>

<httpHandlers>

<add path=”ChartImg.axd” verb=”GET,HEAD” type=”System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ validate=”false”/>

</httpHandlers>

</system.web>

<!–

The system.webServer section is required for running ASP.NET AJAX under Internet

Information Services 7.0. It is not necessary for previous version of IIS.

–>

<system.webServer>

<validation validateIntegratedModeConfiguration=”false”/>

<modules runAllManagedModulesForAllRequests=”true”>

</modules>

<handlers>

<remove name=”UrlRoutingHandler”/>

</handlers>

</system.webServer>

<runtime>

<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>

<dependentAssembly>

<assemblyIdentity name=”System.Web.Mvc” publicKeyToken=”31bf3856ad364e35″/>

<bindingRedirect oldVersion=”1.0.0.0″ newVersion=”2.0.0.0″/>

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

Once you’ve copied over this configuration file, recycle your IIS App Pool and restart your IIS Server. Open the SO-Aware web site, and verify everything works as planned.

Using the SO-Aware PowerShell Provider to Register Services

With the creation of SO-Aware ( http://www.tellagostudios.com ) , a Service Metadata Repository that can do all sorts of things, comes the added benefit of using Microsoft’s Windows PowerShell. To borrow a line from Microsoft’s site, PowerShell is a command line shell and scripting language that helps IT professionals achieve greater control and productivity to more easily control system administration and accelerate automation. We at Tellago Studios, implemented a set of over 40 different standard command line tools to help with the management and control of the SO-Aware Repository. Outlined below are the steps needed to install, register, configure and add SOAP and RESTful Services inside SO-Aware.

How To Install the SO-Aware PowerShell Provider

  1. First Download the PowerShell Provider Setup files here: http://www.tellagostudios.com/projectfiles/SO-Aware_PowerShell.zip
  2. Next extract the files to a directory of your choosing and execute the SO-Aware PowerShell.msi windows installer file as an administrator.
  3. Step through the setup dialogs as such:
  4. After the install has successfully completed, the SO-Aware powershell provider named: “SOAwareSnapIn” are registered to the PowerShell global system. To utilize the SO-Aware commandlets you must open a PowerShell Session and add the SOAwareSnapIn to the current session. At this point, the SO-Aware powershell commandlets can be used.

Working with a PowerShell Session

  1. Open up a PowerShell prompt using Windows Server 2008 (See an icon that looks similar to this:
  2. Inside the PowerShell Command prompt type: add-PSSnapIn SOAwareSnapIn
  3. The above line adds the SO-Aware PowerShell commandlets into the current PowerShell Session. Each session you start up will need to have the snapin added in order to use the SO-Aware PowerShell commmandlets. (There are scripts the you can run in order to alleviate this repetitive process, after the install just navigate to Start->All Programs-> Tellago Studios->SO-Aware->SOAware.ps1)
  4. After you’ve loaded up all the SO-Aware commandlets, we must configure the current SO-Aware PowerShell Provider session to point to the SO-Aware Service Repository. Type in: set-SWEndpoint –url ‘http://localhost:8088/SO-Aware/ServiceRepository.svc&#8217; (Just remember to replace the actual URL with your URL pointing to the SO-Aware Service Repository.

Registering a SOAP Service inside the SO-Aware Repository

  1. To Add any type of service, REST, ODATA or SOAP we use the add-swservice commandlet. To determine exactly which service type we use the Style property.
  2. Inside the PowerShell Command prompt type:    add-swservice -Name ‘People Finder’ -Namespace ‘http://tempuri.org&#8217; -Style ‘SOAP’
  3. Style supports three options: SOAP, REST, ODATA

  4. You should see text that says that the Service was added successfully, otherwise an error will pull up showing you the issue such as:

  5. To complete the Service Registration, we need to Add a ServiceVersion inside the ServiceRepository and attach it to the newly added service.
  6. To Add a Service Version, we use the add-sw[Type]ServiceVersion command let, where [Type] can be either REST, OData, or, SOAP.
  7. However to add the Service Version we first need the Service ID of the newly added service, thus use the get-swServices commandlet to retrieve the newly added service, Service Id
  8. Type: get-swServices –Name ‘People Finder’
  9. This will retrieve all services with the name ‘People Finder’, you could actually leave –Name off and all services registered would return:

  10. When you master PowerShell, you can also filter out values, and pipe it’s contents into other commandlets, such that all I really needed was one command to get the ServiceID, and pass it’s value into the Add Service Version commandlet.
  11. Now that we have the service id, we can add it to the Service Version using the add-swSoapServiceVersion commandlet.
  12. Type: add-swSoapServiceVersion –ServiceId ‘eab4cad9-e0ad-4fd7-941c-2f3641dd89e5’ –Version ‘1.0’ –url ‘http://localhost:1245/PeopleFinder.svc?wsdl‘ –Configuration ‘Production’
  13. Where the ServiceID is the actual Guid from your service, the Version is the actual version number you want to add, Configuration is the category name you want to file the Service Version under, and the Url is the live url location to your WSDL for the SOAP Service.

  14. That’s it. You’re done!
  15. Goto to your SO-Aware Web Site and see your results:
  16. Added Service
  17. Added Service Version:
  18. Added Version Details, inferred from WSDL

Registering a REST and OData Service inside the SO-Aware Repository

  1. To Add either REST or ODATA we use the add-swservice commandlet.
  2. Inside the PowerShell Command prompt type:    add-swservice -Name ‘REST WebService’ -Namespace ‘http://localhost/WebStyle.Host/Service.svc&#8217; -Style ‘REST’
  3. Style supports three options: SOAP, REST, ODATA

  4. You should see text that says that the Service was added successfully
  5. To complete the Service Registration, we need to Add a ServiceVersion inside the ServiceRepository and attach it to the newly added service.
  6. To Add a REST Service Version, we use the add-swRESTServiceVersion command let other than that we use the add-swODataServiceVersion.
  7. However to add the Service Version we first need the Service ID of the newly added service, thus use the get-swServices commandlet to retrieve the newly added service, Service Id
  8. Type: get-swServices –Name ‘REST WebService’
  9. This will retrieve all services with the name ‘REST WebService’, you could actually leave –Name off and all services registered would return:

  10. Now that we have the service id, we can add it to the Service Version using the add-swRESTServiceVersion commandlet.
  11. Type: add-swRESTServiceVersion –ServiceId ‘7ea50e22-7262-4d09-8611-07cf62e8e555’ –Version ‘1.0’ –BaseUri ‘http://localhost:4371/WebStyle.Host/Service.svc ‘ –Configuration ‘Production’
  12. For OData we’d use:
  13. Type: add-swODataServiceVersion –ServiceId ‘7ea50e22-7262-4d09-8611-07cf62e8e555’ –Version ‘1.0’ –ODataUrl ‘http://localhost:4371/WebStyle.Host/Service.svc ‘ –Configuration ‘Production’
  14. Where the ServiceID is the actual Guid from your service, the Version is the actual version number you want to add, Configuration is the category name you want to file the Service Version under, and the BaseUri is the live url location to your Rest Service, or the ODataUrl is the live url location to your REST OData Service.

  15. That’s it. You’re done!
  16. Goto to your SO-Aware Web Site and see your results:

  17. Service Version details:
  18. What you’ll notice here, is that for this version of the SO-Aware PowerShell Commandlets, REST Add Operations are not supported yet, thus you’ll have to Add the operation using the Web based UI manually.

Working with some of the remaining SO-Aware Commandlets

  1. Case in point here, all SO-Aware Commandlets will follow a simple pattern:
    1. GET-SW*s
    2. ADD-SW*
    3. SET-SW*
    4. REMOVE-SW*
    5. Where the “*” is the name of the artifact or entity you’d like to query or update.
  2. So for example if you wanted to get all services you would use: GET-SWServices
  3. To see which parameters that are needed for each commandlet, you can just execute the commandlet inside the PowerShell prompt and the PowerShell prompt will ask you for the required parameters.
  4. To see any optional parameters, you’ll need to download the documentation at: http://tellagostudios.com/sites/default/files/SO-Aware%20API%20Documentation.zip