Bleeding Edge 2011: Pub/Sub Broker Design 

This is the content from my Bleeding Edge 2011 talk on pub/sub broker design and implementation.

Due to constraints of the project (European Commission, funded by EU) I cannot publicly distribute the implementation code at this time. I plan to do it after the review process is done. It has been advised, that this probably won't be the case.

Specifically, this is:

  • A message based pub/sub broker
  • Can use typed messages
  • Can be extended
  • Can communicate with anyone
  • Supports push and pull models
  • Can call you back
  • Service based
  • Fast (in memory)
  • Is currently fed by the Twitter gardenhose stream, for your pleasure

Anyway, I can discuss the implementation and design decisions, so here's the PPT (in slovene only).

Downloads: Bleeding Edge 2011, PPTs
Demo front-end: Here

Wednesday, October 05, 2011 10:17:31 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Designing Clean Object Models with SvcUtil.exe 

There are a couple situations where one might use svcutil.exe in command prompt vs. Add Service Reference in Visual Studio.

At least a couple.

I don't know who (or why) made a decision not to support namespace-less proxy generation in  Visual Studio. It's a fact that if you make a service reference, you have to specify a nested namespace.

On the other end, there is an option to make the proxy class either public or internal, which enables one to hide it from the outside world.

That's a design flaw. There are numerous cases, where you would not want to create another [1] namespace, because you are designing an object model that needs to be clean.

[1] This is only limited to local type system namespace declarations - it does not matter what you are sending over the wire.

Consider the following namespace and class hierarchy that uses a service proxy (MyNamespace.Service class uses it):

Suppose that the Service class uses a WCF service, which synchronizes articles and comments with another system. If you use Add Web Reference, there is no way to hide the generated service namespace. One would probably define MyNamespace.MyServiceProxy as a namespace and declared a using statement in MyNamespace.MyService scope with:

using MyNamespace.MyServiceProxy;

This results in a dirty object model - your clients will see your internals and that shouldn't be an option.

Your class hierarchy now has another namespace, called MyNamespace.ServiceProxy, which is actually only used inside the MyNamespace.Service class.

What one can do is insist that the generated classes are marked internal, hiding the classes from the outside world, but still leaving an empty namespace visible for instantiating assemblies.

Leaving only the namespace visible, with no public classes in it is pure cowardness.

Not good.

Since there is no internal namespace modifier in .NET, you have no other way of hiding your namespace, even if you demand internal classes to be generated by the Add Service Reference dialog.

So, svcutil.exe to the rescue:

svcutil.exe <metadata endpoint>
   /namespace:*, MyNamespace
   /internal
   /out:ServiceProxyClass.cs

The /namespace option allows you to map between XML and CLR namespace declarations. The preceding examples maps all (therefore *) existing XML namespaces in service metadata to MyNamespace CLR namespace.

The example will generate a service proxy class, mark it internal and put it into the desired namespace.

Your object model will look like this:

Currently, this is the only way to hide the internals of service communication with a proxy and still being able to keep your object model clean.

Note that this is useful when you want to wrap an existing service proxy or hide a certain already supported service implementation detail in your object model. Since your client code does not need to have access to complete service proxy (or you want to enhance it), it shouldn't be a problem to hide it completely.

Considering options during proxy generation, per method access modifiers would be beneficial too.

Categories:  .NET 3.5 - WCF | Web Services
Friday, April 10, 2009 10:06:43 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Bleeding Edge 2008: Postback 

I'm sorry it took a week, but here we go.

This is my exit content from Bleeding Edge 2008. I'm also posting complete conference contents, just in case.

Thanks go out to Dušan, Dejan, Miha, Miha and Miha.

Downloads:

Remark: PPT in Slovene only. Code international.

Thank you for attending. Hope to see you next year!

Categories:  CLR | Conferences | Microsoft | Web Services | Work
Thursday, October 09, 2008 8:42:02 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WCF: Passing Collections Through Service Boundaries, Why and How 

In WCF, collection data that is passed through the service boundary goes through a type filter - meaning you will not necessarily get the intrinsic service side type on the client, even if you're expecting it.

No matter if you throw back an int[] or List<int>, you will get the int[] by default on the client.

The main reason is that there is no representation for System.Collections.Generic.List or System.Collection.Generic.LinkedList in service metadata. The concept of System.Collection.Generic.List<int> for example, actually does not have a different semantic meaning from an integer array - it's still a list of ints - but will allow you to program against it with ease.

Though, if one asks nicely, it is possible to guarantee the preferred collection type on the client proxy in certain scenarios.

Unidimensional collections, like List<T>, LinkedList<T> or SortedList<T> are always exposed as T arrays in the client proxy. Dictionary<K, V>, though, is regened on the client via an annotation hint in WSDL (XSD if we are precise). More on that later.

Let's look into it.

WCF infrastructure bends over backwards to simplify client development. If the service side contains a really serializable collection (marked with [Serializable], not [DataContract]) that is also concrete (not an interface), and has an Add method with the following signatures...

public void Add(object obj);
public void Add(T item);

... then WCF will serialize the data to an array of the collections type.

Too complicated? Consider the following:

[ServiceContract]
interface ICollect
{
   [OperationContract]
   public void AddCoin(Coin coin);

   [OperationContract]
   public List<Coin> GetCoins();
}

Since the List<T> supports a void Add<T> method and is marked with [Serializable], the following wire representation will be passed to the client:

[ServiceContract]
interface ICollect
{
  [OperationContract]
  void AddCoin(Coin coin);

  [OperationContract]
  Coin[] GetCoins();
}

Note: Coin class should be marked either with a [DataContract] or [Serializable] in this case.

So what happens if one wants the same contract on the client proxy and the service? There is an option in the WCF proxy generator, svcutil.exe to force generation of class definitions with a specific collection type.

Use the following for List<T>:

svcutil.exe http://service/metadata/address
  /collectionType:System.Collections.Generic.List`1

Note: List`1 uses back quote, not normal single quote character.

What the /collectionType (short /ct) does, is forces generation of strongly typed collection types. It will generate the holy grail on the client:

[ServiceContract]
interface ICollect
{
  [OperationContract]
  void AddCoin(Coin coin);

  [OperationContract]
  List<Coin> GetCoins();
}

In Visual Studio 2008, you will even have an option to specify which types you want to use as collection types and dictionary collection types, as in the following picture:

On the other hand, dictionary collections, as in System.Collections.Generic.Dictionary<K, V> collections, will go through to the client no matter what you specify as a /ct parameter (or don't at all).

If you define the following on the service side...

[OperationContract]
Dictionary<string, int> GetFoo();

... this will get generated on the client:

[OperationContract]
Dictionary<string, int> GetFoo();

Why?

Because using System.Collections.Generic.Dictionary probably means you know there is no guarantee that client side representation will be possible if you are using an alternative platform. There is no way to meaningfully convey the semantics of a .NET dictionary class using WSDL/XSD.

So, how does the client know?

In fact, the values are serialized as joined name value pair elements as the following schema says:

<xs:complexType name="ArrayOfKeyValueOfstringint">
  <xs:annotation>
    <xs:appinfo>
      <IsDictionary
        xmlns="
http://schemas.microsoft.com/2003/10/Serialization/">
        true
      </IsDictionary>
    </xs:appinfo>
  </xs:annotation>
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded"
      name="KeyValueOfstringint">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="Key" nillable="true" type="xs:string" />
          <xs:element name="Value" type="xs:int" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfKeyValueOfstringint"
  nillable="true" type="tns:ArrayOfKeyValueOfstringint" />

Note: You can find this schema under types definition of the metadata endpoint. Usually ?xsd=xsd2, instead of ?wsdl will suffice.

As in:

<GetFooResponse>
  <KeyValueOfstringint>
    <Key>one</Key>
    <Value>1</Value>

    <Key>two</Key>
    <Value>2</Value>

    <!-- ... -->

    <Key>N</Key>
    <Value>N</Value>
  </KeyValueOfstringint>
<GetFooResponse>

The meaningful part of type service-to-client-transportation resides in <xs:annotation> element, specifically in /xs:annotation/xs:appinfo/IsDictionary element, which defines that this complex type represents a System.Collections.Generic.Dictionary class. Annotation elements in XML Schema are parser specific and do not convey any structure/data type semantics, but are there for the receiver to interpret.

This must be one of the most excellent school cases of using XML Schema annotations. It allows the well-informed client (as in .NET client, VS 2008 or svcutil.exe) to utilize the semantic meaning if it understands it. If not, no harm is done since the best possible representation, in a form of joined name value pairs still goes through to the client.

Categories:  .NET 3.0 - WCF | .NET 3.5 - WCF | Web Services
Thursday, September 27, 2007 10:04:47 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Approaches to Document Style Parameter Models 

I'm a huge fan of document style parameter models when implementing a public, programmatic façade to a business functionality that often changes.

public interface IDocumentParameterModel
{
   [OperationContract]
   [FaultContract(typeof(XmlInvalidException))]
   XmlDocument Process(XmlDocument doc);
}

This contract defines a simple method, called Process, which processes the input document. The idea is to define the document schema and validate inbound XML documents, while throwing exceptions on validation errors. The processing semantics is arbitrary and can support any kind of action, depending on the defined invoke document schema.

A simple instance document which validates against a version 1.0 processing schema could look like this:

<?xml version="1.0?>
<Process xmlns="http://www.gama-system.com/process10.xsd" version="1.0">
   <Instruction>Add</Instruction>
   <Parameter1>10</Parameter1>
   <Parameter2>21</Parameter2>
</Process>

Another processing instruction, supported in version 1.1 of the processing schema, with different semantics could be:

<?xml version="1.0?>
<Process xmlns="http://www.gama-system.com/process11.xsd" version="1.1">
   <Instruction>Store</Instruction>
   <Content>77u/PEFwcGxpY2F0aW9uIHhtbG5zPSJod...mdVcCI</Content>
</Process>

Note that the default XML namespace changed, but that is not a norm. It only allows you to automate schema retrieval using the schema repository (think System.Xml.Schema.XmlSchemaSet), load all supported schemas and validate automatically.

public class ProcessService : IDocumentParameterModel
{
   public XmlDocument Process(XmlDocument doc)
   {
      XmlReaderSettings sett = new XmlReaderSettings();

      sett.Schemas.Add(<document namespace 1>, <schema uri 1>);
      ...
      sett.Schemas.Add(<document namespace n>, <schema uri n>);

      sett.ValidationType = ValidationType.Schema;
      sett.ValidationEventHandler += new
         ValidationEventHandler(XmlInvalidHandler);
      XmlReader books = XmlReader.Create(doc.OuterXml, sett);
      while (books.Read()) { }

      // processing goes here
      ...
   }

   static void XmlInvalidHandler(object sender, ValidationEventArgs e)
   {
      if (e.Severity == XmlSeverityType.Error)
         throw new XmlInvalidException(e.Message);
   }
}

The main benefit of this approach is decoupling the parameter model and method processing version from the communication contract. A service maintainer has an option to change the terms of processing over time, while supporting older version-aware document instances.

This notion is of course most beneficial in situations where your processing syntax changes frequently and has complex validation schemas. A simple case presented here is informational only.

So, how do we validate?

  • We need to check the instance document version first. This is especially true in cases where the document is not qualified with a different namespace when the version changes.
  • We grab the appropriate schema or schema set
  • We validate the inbound XML document, throw a typed XmlInvalidException if invalid
  • We process the call

The service side is quite straightforward.

Let's look at the client and what are the options for painless generation of service calls using this mechanism.

Generally, one can always produce an instance invoke document by hand on the client. By hand meaning using System.Xml classes and DOM concepts. Since this is higly error prone and gets tedious with increasing complexity, there is a notion of a schema compiler, which automatically translates your XML Schema into the CLR type system. Xsd.exe and XmlSerializer are your friends.

If your schema requires parts of the instance document to be digitally signed or encrypted, you will need to adorn the serializer output with some manual DOM work. This might also be a reason to use the third option.

The third, and easiest option for the general developer, is to provide a local object model, which serializes the requests on the client. This is an example:

ProcessInstruction pi = new ProcessInstruction();
pi.Instruction = "Add";
pi.Parameter1 = 10;
pi.Parameter2 = 21;
pi.Sign(cert); // pi.Encrypt(cert);
pi.Serialize();
proxy.Process(pi.SerializedForm);

The main benefit of this approach comes down to having an option on the server and the client. Client developers have three different levels of complexity for generating service calls. The model allows them to be as close to the wire as they see fit. Or they can be abstracted completely from the wire representation if you provide a local object model to access your services.

Categories:  .NET 3.0 - WCF | .NET 3.5 - WCF | Architecture | Web Services | XML
Monday, September 24, 2007 11:19:10 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Managed TxF: Distributed Transactions and Transactional NTFS 

Based on my previous post, I managed to get distributed transaction scenario working using WCF, MTOM and WS-AtomicTransactions.

This means that you have the option to transport arbitrary files, using transactional ACID semantics, from the client, over HTTP and MTOM.

The idea is to integrate a distributed transaction with TxF, or NTFS file system transaction. This only works on Windows Server 2008 (Longhorn Server) and Windows Vista.

Download: Sample code

If the client starts a transaction then all files within it should be stored on the server. If something fails or client does not commit, no harm is done. The beauty of this is that it's all seamlessly integrated into the current communication/OS stack.

This is shipping technology; you just have to dive a little deeper to use it.

Here's the scenario:

There are a couple of issues that need to be addressed before we move to the implementation:

  • You should use the managed wrapper included here
    There is support for TransactedFile and TransactedDirectory built it. Next version of VistaBridge samples will include an updated version of this wrapper.

  • Limited distributed transactions support on a system drive
    There is no way to get DTC a superior access coordinator role for TxF on the system drive (think c:\ system drive). This is a major downside in the current implementation of TxF, since I would prefer that system/boot files would be transaction-locked anyway. You have two options if you want to run the following sample:

    • Define secondary resource manager for your directory
      This allows system drive resource manager to still protect system files, but creates a secondary resource manager for the specified directory. Do this:
      • fsutil resource create c:\txf
      • fsutil resource start c:\txf
        You can query your new secondary resource manager by fsutil resource info c:\txf.

    • Use another partition
      Any partition outside the system partition is ok. You cannot use network shares, but USB keys will work. Plug it in and change the paths as defined at the end of this post.

OK, here we go.

Here's the service contract:

[ServiceContract(SessionMode = SessionMode.Allowed)]
interface ITransportFiles
{
   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   byte[] GetFile(string name);

   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   void PutFile(byte[] data, string name);

We allow the sessionful binding (it's not required, though) and allow transactions to flow from the client side. Again, transactions are not mandatory, since client may opt-out of using them and just transport files without a transaction.

The provided transport mechanism uses MTOM, since the contract's parameter model is appropriate for it and because it's much more effective transferring binary data.

So here's the service config:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="MTOMBinding"
          transactionFlow="true"
          messageEncoding="Mtom"
          maxReceivedMessageSize="10485760">
        <readerQuotas maxArrayLength="10485760"/>

      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
    <service name="WCFService.TransportService">
      <host>
        <baseAddresses>
          <add baseAddress="
http://localhost:555/transportservice">
        </baseAddresses>
      </host>
      <endpoint address=""
          binding="wsHttpBinding"
          bindingConfiguration="MTOMBinding"
          contract="WCFService.ITransportFiles"/>
    </service>
  </services>
</system.serviceModel>

Here, MTOMBinding is being used to specify MTOM wire encoding. Also, quotas and maxReceivedMessageSize attribute is being adjusted to 10 MB, since we are probably transferring larger binary files.

Service implementation is straight forward:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class TransportService : ITransportFiles
{
    [OperationBehavior(TransactionScopeRequired = true)]
    public byte[] GetFile(string name)
    {
        Console.WriteLine("GetFile: {0}", name);
        Console.WriteLine("Distributed Tx ID: {0}",
          Transaction.Current.TransactionInformation.DistributedIdentifier);
        return ReadFully(TransactedFile.Open(@"C:\TxF\Service\" + name,
          FileMode.Open, FileAccess.Read, FileShare.Read), 0);
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public void PutFile(byte[] data, string filename)
    {
        Console.WriteLine("PutFile: {0}", filename);
        Console.WriteLine("Distributed Tx ID: {0}",
          Transaction.Current.TransactionInformation.DistributedIdentifier);

        using (BinaryWriter bw = new BinaryWriter(
            TransactedFile.Open(@"C:\TxF\Service\" + filename,
              FileMode.Create, FileAccess.Write, FileShare.Write)))
        {
            bw.Write(data, 0, data.Length);
           
            // clean up
            bw.Flush();
        }
    }
}

Client does four things:

  1. Sends three files (client - server) - no transaction
  2. Gets three files (server - client) - no transaction
  3. Sends three files (client - server) - distributed transaction, all or nothing
  4. Gets three files (server - client) - distributed transaction, all or nothing

Before you run:

  • Decide on the secondary resource manager option (system drive, enable it using fsutil.exe) or use another partition (USB key)
  • Change the paths to your scenario. The sample uses C:\TxF, C:\TxF\Service and C:\TxF\Client and a secondary resource manager. Create these directories before running the sample.

Download: Sample code

This sample is provided without any warranty. It's a sample, so don't use it in production environments.

Monday, July 23, 2007 9:54:13 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WS-Management: Windows Vista and Windows Server 2008 

I dived into WS-Management support in Vista / Longhorn Server Windows Server 2008 this weekend. There are a couple of caveats if you want to enable remote WS-Management based access to these machines. Support for remote management is also built into Windows Server 2003 R2.

WS-Management specification allows remote access to any resource that implements the specification. Everything accessed in a WS-Management world is a resource, which is identifiable by a URI. The spec uses WS-Eventing, WS-Enumeration, WS-Transfer and SOAP 1.2 via HTTP.

Since remote management implementation in Windows acknowledges all the work done in the WMI space, you can simply issue commands in terms of URIs that incorporate WMI namespaces.

For example, the WMI class or action (method) is identified by a URI, just as any other WS-Management based resource. You can construct access to any WMI class / action using the following semantics:

  • http://schemas.microsoft.com/wbem/wsman/1/wmi denotes a default WMI namespace accessible via WS-Management
  • http://schemas.microsoft.com/wbem/wsman/1/wmi/root/default denotes access to root/default namespace

Since the majority of WMI classes are in root/cimv2 namespace, you should use the following URI to access those:

http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2

OK, back to WS-Management and its implementation in Vista / Windows Server 2008.

First, Windows Server 2008 has the Windows Remote Management service started up by default. Vista doesn't. So start it up, if you're on a Vista box.

Second, depending on your network configuration, if you're in a workgroup environment (not joined to a domain) you should tell your client to trust the server side.

Trusting the server side involves executing a command on a client. Remote management tools included in Windows Server 2008 / Windows Vista are capable of configuring the local machine and issuing commands to remote machine. There are basically two tools which allow you to setup the infrastructure and issue remote commands to the destination. They are:

  • winrm.cmd (uses winrm.vbs), defines configuration of local machine
  • winrs.exe (winrscmd.dll and friends), Windows Remote Shell client, issues commands to a remote machine

As said, WS-Management support is enabled by default in Windows Server 2008. This means that the appropriate service is running, but one should still define basic configuration on it. Nothing is enabled by default; you have to opt-in.

Since Microsoft is progressing to a more admin friendly environment, this is done by issuing the following command (server command):

winrm quickconfig (or winrm qc)

This enables the obvious:

  • Starts the Windows Remote Management service (if not stared; in Windows Vista case)
  • Enables autostart on the Windows Remote Management service
  • Starts up a listener for all machine's IP addresses
  • Configures appropriate firewall exceptions

You should get the following output:

[c:\windows\system32]winrm quickconfig

WinRM is not set up to allow remote access to this machine for management.
The following changes must be made:

Create a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.
Enable the WinRM firewall exception.

Make these changes [y/n]? y

WinRM has been updated for remote management.
Created a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.
WinRM firewall exception enabled.

There are options in winrm.cmd to fine tune anything, including the listening ports and / or SSL (HTTPS) support. In a trusted environment you probably don't want to issue commands using HTTP based mechanism, since you are located behind the trust boundary and have complete control over available (allowed) TCP ports.

You can now issue remote management commands against the configured server, but only if the communication is trusted. So in case you are in a workgroup environment (client and server in a workgroup), this should get you started (client command):

winrm set winrm/config/client @{TrustedHosts="<server ip or hostname>"}

You can specify multiple trusted servers using a comma:

winrm set winrm/config/client @{TrustedHosts="10.10.10.108, 10.10.10.109"}

This trusts the server(s) no matter what. Even over HTTP only.

Enumerating the configured listeners - remember, listener is located on the destination side - is done via:

winrm enumerate winrm/config/listener

OK, now we're able to issue commands to the remote side using WS-Management infrastructure. You can, for example, try this (client command):

winrs -r:http://<server ip> -u:<username> -p:<password> <shell command>, ie.
winrs -r:http://10.10.10.108 -u:administrator -p:p$38E0jjW! dir -s

or

winrs -r:http://10.10.10.108 -u:administrator -p:p$38E0jjW! hostname

You can even explose HTTP based approach through your firewall if you're crazy enough. But using HTTPS would be the smart way out. What you need is a valid certificate with server authentication capability and a matching CN. Self-signed certs won't work.

Simple and effective.

Categories:  Web Services | Windows Vista
Sunday, July 22, 2007 7:48:22 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Out the Door: WS-ReliableMessaging 1.1 

WS-RM 1.1 is finished. GoodTimestm.

OASIS published two specs:

WCF, as it turns out, will have support for WS-RM 1.1 implementation in Orcas. On this note, there is a new CTP out this week.

Categories:  .NET 3.5 - WCF | Microsoft | Web Services
Tuesday, July 03, 2007 3:58:29 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Durable Messaging Continues 

Nick is continuing my discussion on durable messaging support in modern WS-* based stacks, especially WCF.

I agree that having a simple channel configuration support to direct messages into permanent information source (like SQL) would be beneficial.

A simple idea that begs for an alternative implementation of a WCF extensibility point, has some questions:

  • What happens when messages are (or should be) exchanged in terms of a transaction context?
  • How can we demand transaction support from the underlying datastore, if we don't want to put limitations onto anything residing beind the service boundary?
  • What about security contexts? How can we acknowledge a secure, durable sessionful channel after two weeks of service hibernation down time? Should security keys still be valid just because service was down and not responding all this time?
  • Is durability limited to client/service recycling or non-memory message storage? What about both?

Is [DurableService]enough?

Wednesday, May 30, 2007 9:46:14 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WS-* has an Open Specification Promise 

Microsoft has issued a statement that all (jointly) developed web services specifications have an "open use" policy attached to them.

Legal talk:

"Microsoft irrevocably promises not to assert any Microsoft Necessary Claims against you for making, using, selling, offering for sale, importing or distributing any implementation to the extent it conforms to a Covered Specification (“Covered Implementation”), subject to the following. This is a personal promise directly from Microsoft to you, and you acknowledge as a condition of benefiting from it that no Microsoft rights are received from suppliers, distributors, or otherwise in connection with this promise. If you file, maintain or voluntarily participate in a patent infringement lawsuit against a Microsoft implementation of such Covered Specification, then this personal promise does not apply with respect to any Covered Implementation of the same Covered Specification made or used by you. To clarify, “Microsoft Necessary Claims” are those claims of Microsoft-owned or Microsoft-controlled patents that are necessary to implement only the required portions of the Covered Specification that are described in detail and not merely referenced in such Specification. “Covered Specifications” are listed below."

The promise is given to the specifications themselves and, of course, not to implementations.

GoodMovetm.

Categories:  Web Services
Wednesday, September 13, 2006 10:13:14 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Article: Transactional Semantics in Loosely Coupled Distributed Systems 

Last article finished my XML series. This one focuses on transactional semantics in a service oriented universe.

Language: Slovenian


Naslov:

Transakcijska semantika v šibko sklopljenih, porazdeljenih sistemih

Transakcijska semantika v šibko sklopljenih, porazdeljenih sistemih

Tuesday, June 06, 2006 9:59:30 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Article: Concepts and Semantics of Service Contracts 

The second article is about concepts and semantics of service contracts. It deals with WCF (Windows Communication Foundation) contract definition and its behavioral aspects.

Language: Slovenian


Naslov:

Koncepti in semantike storitvenih pogodb

Koncepti in semantike storitvenih pogodb

Categories:  .NET 3.0 - WCF | Architecture | Articles | Web Services
Friday, June 02, 2006 7:19:45 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 On AJAX being dead 

A fellow MVP, Daniel Cazzulino, has a post titled AJAX may be the biggest waste of time for the web. While I agree with most of the points there, one should think about what Microsoft is doing to lower the AJAX development experience boundary.

Having to deal with JavaScript, raw (D)HTML and XML is definitely not going to scale from the developer penetration perspective. Nobody wants to do this is 2006. Therefore if Atlas guys make their magic happen, this would actually not be neccessary. It they achieve what they started, one would be abstracted from client side programming in most of the situations.

<atlas:UpdatePanel/> and <atlas:ScriptManager/> are your friends. And they could go a long way.

If this actually happens then we are actually discussing whether rich web based apps are more appropriate for the future web. There are scenarios that benefit from all these technologies, obviously. And if the industry concludes that DHTML with XmlHttpRequests is not powerful enough, who would stop the same model to produce rich WPF/E code from being emitted out of an Atlas enabled app.

We have, for the most part, been able to abstract the plumbing that is going on behind the scenes. If it's server side generated code, that should be running on a client, and if it is JavaScript, because all browsers run it, so be it.

We have swallowed the pill on the SOAP stacks already. We don't care if the communication starts with a SCT Request+Response messages, following by the key exchange. We do not care that a simple request-response model produces 15 messages while starting up. We do not care that there is raw XML being transfered. After all, it is all a fog, doing what it is supposed to do best - hiding the abstraction behind our beautiful SOAP/Services stack API.

Categories:  Other | Web Services | XML
Saturday, May 27, 2006 11:07:39 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Windows Workflow Foundation: Running Service Activated Workflows on Windows Vista and IIS7 

This post will focus on how to enable IIS7 in Windows Vista client and to use it to host a service activated Windows Workflow.

Procedure is based on the current build of Windows Vista (5381.1), which is a RC1 for Beta 2 milestone. Also, WinFX February CTP is used, which includes Windows Workflow Foundation Beta 2.

There are a couple of prerequisite steps necessary to enable hosting, first of all, installing IIS7. Go to Control Panel/Programs/Turn on or off Windows Features and enable 'Internet Information Services':

Add or remove Windows features

Installer in build 5381.1 (and 5365) is stable enough to be useful. If you're running a previous build of Vista (5308, 5342) consider installing IIS by running this monster in the command prompt:

start /w pkgmgr /l:log.etw /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ASP;IIS-CGI;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ODBCLogging;IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;IIS-ClientCertificateMappingAuthentication;IIS-IISCertificateMappingAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;IIS-WebServerManagementTools;IIS-ManagementConsole;IIS-ManagementScriptingTools;IIS-ManagementService;IIS-IIS6ManagementCompatibility;IIS-Metabase;IIS-WMICompatibility;IIS-LegacyScripts;IIS-LegacySnapIn;IIS-FTPPublishingService;IIS-FTPServer;IIS-FTPManagement;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI

Make sure you also check ASP.NET under World Wide Web Services/Application Development features, since this will install and enable ASP .NET 2.0 under all IIS7 sites. You can also do this later on using aspnet_regiis.exe, but Vista will notify you that the preferred way is using Turn on or off Windows features dialog.

Now, when you have IIS installed run the administrative console inside Administrative Tools and define a web application by right clicking on Default Web Site:

Creating application on IIS7

This will allow you to run your workflow as a service inside the default application pool. You can check and notice that default application pool uses a new integrated IIS7 mode and not ISAPI as in IIS5/6.

You're ready to deploy your workflow activated service now. use the steps described in my previous post, under Ad 1.

When you hit the service endpoint you get this:

Configuration error in IIS7

IIS7 is noticing you that your config files are not compatible with the new hosting model.

You have two options:

  • Change the configuration files
  • Change the hosting model

You can change the configuration files by running: c:\windows\system32\inetsrv\appcmd.exe migrate config "<Site name>/<VRoot name>". AppCmd.exe is a tool which automatically migrates your old config, to IIS7's new config format.

Another option is that you enable old style ISAPI hosting model inside your application pool that is running your default web site (or another site, if that's what the workflow is supposed to be running under). You can do this either by:

1. Running c:\windows\system32\inetsrv\appcmd.exe set app "<Site name>/<VRoot name>" /applicationPool: "Classic .NET AppPool". This changes the site to use another, preconfigured app pool, which uses ISAPI by default.

Here's a screenshot of the default pipeline modes for IIS7:

Application pool config in IIS7

2. Changing the hosting model on the current Default Web Site site. You can right click on Application Pools/DefaultAppPool and select Set Application Pool Defaults. Then you change the pipeline mode from Integrated to ISAPI. Here's how you do it:

Pipeline mode selection

I prefer going through route 1. Integrated mode is how you should be running your sites under IIS7, so changing the config to make IIS7 happy is the way to go. If you have specific ISAPI functionality (not limited to Workflows) you can, though run in classic mode by designing your app pool around it.

Now your service activated workflow will run and execute under IIS7. Again, beware of the caveats I described here.

Categories:  Web Services | Windows Vista | .NET 3.0 - WF
Thursday, May 11, 2006 11:15:46 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Windows Workflow Foundation: Exposing Workflows as Services 

There are currently a couple of options to expose a Windows Workflow as as service.

  1. There is a native option to publish a developed Workflow Library project as a ASP .NET Web Service (ASMX).
  2. You can host it yourself (ASMX, WCF)
  3. William Tay is doing excellent work towards hosting a workflow inside the WCF service pipeline (WCF)
  4. Roman Kiss created a static WorkflowInvoker class, which does all the heavy liting for you, if you want to host your workflow inside the WCF service method (WCF)

I'm going to focus on Ad 1 and Ad 2 in this post.

Ad 1:

There's an option to host your workflow library inside a web service by using a "Publish as a Web Service" option inside Visual Studio 2005. This creates a separate ASP .NET Web Service project inside your current solution, which you can later manually or automatically publish as a web site to your IIS of choice.

The are two major downsides to this story. The first is that this gives you practically no control over how the web service is created. Second downside, while documented, is that the current implementation of System.Workflow.Runtime.WorkflowWebHostingModule works in particular ways with the workflow persistence story.

Let's assume we have to following interface defined for this web service:

interface IServiceInterface
{
   void SendOrder(Order order);
   Order GetOrder(Guid guidOrder);
   int GetOrderStatus(Guid guidOrder);
}

What happens is (request number 1):

  1. You publish your workflow as a web service
  2. You hit the service endpoint with a browser
  3. Workflow instance gets created, is run and returns a result
  4. At this time the workflow runtime (System.Workflow.Runtime.WorkflowRuntime instance) creates a workflow instance and runs it. Since workflow completes succesfully it destroys the instance at the end of execution.
  5. Workflow runtime returns a cookie with the workflow instance back to the browser and since IE's default setting is to accept cookies, it is written to the client's disk

All good, right?

Actually, what happens during request number 2?

  1. You hit the endpoint again
  2. IE knows that the site has a persisted cookie, so it sends it bundled with the SOAP request
  3. Workflow runtime sees it and tries to load the specified workflow instance
  4. This instance is long gone, it does not exist in memory (it has been destroyed, remember?), so workflow runtime tries to rehydrate it from a persistence store. If there is a persistence store defined it goes there (most probably WorkflowPersistenceStore in SQL Server) and correctly identifies that the workflow instance is not present, so it fails with 'Workflow with id <GUID> not found in state persistence store.'. If the persistence store is not defined for this workflow it fails with 'The workflow hosting environment does not have a persistence service as required by an operation on the workflow instance <GUID>.'.

And all this is actually the expected behavior if you think hard enough. Workaround? Hit the endpoint with a newly loaded IE window. It works every time, since a cookie with an instance ID is not present.

Another thing to mention here is that this issue does not manifest itself if you hit the endpoint programatically using the web service proxy, unless you are using a CookieContainer class to cache the returning cookies.

Ad 2:

Hosting a Windows Workflow manually is another option, which gives you more flexibility towards the service detail tweeking.

You can host it using the following code:

[WebService(Namespace = "http://webservices.gama-system.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WorkflowService : System.Web.Services.WebService
{
    // workflow runtime
    private static WorkflowRuntime workflowRuntime = new WorkflowRuntime();
    
    [WebMethod]
    public void SendOrder(Order order)
    {
        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted +=
           delegate(object sender, WorkflowCompletedEventArgs e)
        {
            waitHandle.Set();
        };
       
        workflowRuntime.WorkflowTerminated +=
           delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            waitHandle.Set();
        };

        // create workflow instance with the specified parameters
        WorkflowInstance instance =
           workflowRuntime.CreateWorkflow(typeof(MyWorkflow));
        instance.Start();

        waitHandle.WaitOne();
    }   
}

An important thing in the specified sample is that the System.Workflow.Runtime.WorkflowRuntime instance is static to the service implementation class. This is a requirement, since the workflow runtime can only get loaded once per appdomain. If this is not the case you will get an exception during the second invocation of the workflow.

If you are using any additional workflow runtime services, like persistence, tracking or your own communication service to communicate with the workflow you will need to track that the services get loaded once only. Here's the example:

[WebService(Namespace = "http://webservices.gama-system.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WorkflowService : System.Web.Services.WebService
{
    // workflow runtime
    private static WorkflowRuntime workflowRuntime = new WorkflowRuntime();
   
   
// services added
    private static bool booServicesAdded = false;

    // communication service
    private static CommunicationService objComm = new CommunicationService();

    [WebMethod]
    public void SendOrder(Order order)
    {
        // add communication service
        if (!booServicesAdded)
        {
            ExternalDataExchangeService externalService =
               new ExternalDataExchangeService();
            workflowRuntime.AddService(externalService);
            externalService.AddService(objComm);
            booServiceAdded = true;
        }

        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted +=
           delegate(object sender, WorkflowCompletedEventArgs e)
        {
            waitHandle.Set();
        };
       
        workflowRuntime.WorkflowTerminated +=
           delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            waitHandle.Set();
        };

        // create workflow instance with the specified parameters
        WorkflowInstance instance =
           workflowRuntime.CreateWorkflow(typeof(MyWorkflow));
        instance.Start();

        waitHandle.WaitOne();
    }   
}

This adds the required services only during the first invocation of a web service. Since workflow runtime is a static class the services get persisted during all subsequent service calls. A boolean variable booServicesAdded is responsible for flag storage.

Categories:  Web Services | .NET 3.0 - WCF | .NET 3.0 - WF
Wednesday, May 10, 2006 9:55:37 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WinFX January 2006 CTP Released 

WinFX January 2006 CTP just went live.

With it, a Go-Live licence is available for WCF and WF. Sign and deploy.

Update: They managed to screw up the download links again. Beware: If you're downloading complete installs (and not the setup manager) use the lower links for x86 and x64 images (there are two on the get the beta page).

The following links will lead to correct complete download of WinFX January 2006 CTP Runtime Components:

You can also check the file version. The correct WinFX RTC version for January 2006 CTP is 3.0.50727.154 (file size 44.488 KB [x86] and 84.464 KB [x64]). December CTP was 3.0.50727.151 and file sizes were a couple KB lower.

Categories:  Web Services | .NET 3.0 - General | Work
Wednesday, January 18, 2006 9:34:01 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Indigo - Multiple endpoints 

There is a common functionality request in modern distributed applications that clients and services (client also being other services) could communicate using different communication protocols and/or different transport semantics inside a single protocol.

For this sample we're going to limit ourselves to HTTP messaging, but this does not limit the scope of the article. Other transport protocols can be added without obstructing other transport mechanisms.

To allow this scenario Indigo (Windows Communication Foundation, WCF) allows multiple endpoints per service to be setup. Service side bindings can, for example, be the following:

<bindings>
  <wsProfileBinding>
    <binding
      configurationName="Secure"
      orderedSession="false"
      reliableSessionEnabled="false"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="NotAllowed"
      messageEncoding="Text">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
    <binding
      configurationName="SecureReliable"
      orderedSession="true"
      reliableSessionEnabled="true"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="NotAllowed"
      messageEncoding="Text">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
    <binding
      configurationName="SecureReliableTransacted"
      orderedSession="true"
      reliableSessionEnabled="true"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="Allowed"
      messageEncoding="Text">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
    <binding
      configurationName="SecureMTOM"
      orderedSession="false"
      reliableSessionEnabled="false"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="NotAllowed"
      messageEncoding="Mtom">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
    <binding
      configurationName="SecureReliableMTOM"
      orderedSession="true"
      reliableSessionEnabled="true"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="NotAllowed"
      messageEncoding="Mtom">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
   <binding
      configurationName="SecureReliableTransactedMTOM"
      orderedSession="true"
      reliableSessionEnabled="true"
      securityMode="WSSecurityOverHttp"
      maxMessageSize="134217728"
      flowTransactions="Allowed"
      messageEncoding="Mtom">
      <wsSecurity
        authenticationMode="Certificate"
        useNegotiation="true" />
    </binding>
  </wsProfileBinding>
</bindings>

There are six different bindings setup:

  • Secure
  • SecureReliable
  • SecureReliableTransacted
  • SecureMTOM
  • SecureReliableMTOM
  • SecureReliableTransactedMTOM

The Secure binding uses WS-Security/WS-SecureConversation pair to secure all outgoing and incoming messages using encryption and digital signing. We’re not going to drill down into it in this post. I’m going to write another one where different certificate mechanisms will be discussed.

The SecureReliable binding also uses WS-ReliableMessaging with message ordering and guaranteed delivery turned on.

The SecureReliableTransacted endpoint also uses WS-AtomicTransaction to implement transaction semantics between the client and the service.
There are another three bindings (*MTOM) with the same transport semantics as well as MTOM encoding turned on. Since services can support transfer of large binary files, we have also set the maxMessageSize attribute in every binding to 128 MB.

Endpoint configuration for this service is:

<services>
  <service
    serviceType="Indigo.Demos.TransferService"
    behaviorConfiguration="DefaultBehavior">
    <endpoint
      address="
http://localhost:666/TransferService.svc/"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="Default"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureReliableMTOM"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
        "
http://localhost:666/TransferService.svc/secure"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="Secure"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="Secure"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
        "
http://localhost:666/TransferService.svc/
        securereliable"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="SecureReliable"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureReliable"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
        "
http://localhost:666/TransferService.svc/
          securereliabletransacted"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="SecureReliableTransacted"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureReliableTransacted"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
        "
http://localhost:666/TransferService.svc/
          secureMTOM"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="SecureMTOM"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureMTOM"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
      "
http://localhost:666/TransferService.svc/
        securereliableMTOM"
      bindingNamespace=
       "
http://webservices.gama-system.com/bindings"
      bindingName="SecureReliableMTOM"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureReliableMTOM"
      contractType="Indigo.Demos.ITransferContract"/>
    <endpoint
      address=
        "
http://localhost:666/TransferService.svc/
          securereliabletransactedMTOM"
      bindingNamespace=
        "
http://webservices.gama-system.com/bindings"
      bindingName="SecureReliableTransactedMTOM"
      bindingSectionName="wsProfileBinding"
      bindingConfiguration="SecureReliableTransactedMTOM"
      contractType="Indigo.Demos.ITransferContract"/>
  </service>
</services>

It can be seen that almost every endpoint (two are bound to the same binding) is bound to a different binding.
The service is therefore exposing its functionality using the following endpoints:

The first endpoint in this example is considered a default one and is mapped to the same binding as the *securereliableMTOM endpoint.

The problem with this is that current WCF’s WSDLExporter maps different endpoints into WSDL ports, but WSDL ports have a requirement to be uniquely named. The default port name construction is done by using the binding type name (i.e. wsProfileBinding, basicProfileBinding), which is concatenated with the contract name.

Therefore, when one has defined multiple bindings from the same binding type a name collision occurs (six WSDL ports with the same QName (namespace and local name)). This can be avoided using a bindingNamespace attribute as well as bindingName attribute. In this example we set the bindingNamespace to http://webservices.gama-system.com/bindings for all bindings and made the name unique by using the bindingName attribute.

There are currently two weird design decisions in multiple binding support of WCF. First bindingNamespace and bindingName attributes are bound to endpoints and not bindings. It would probably be more appropriate to put binding’s namespace and name into the <binding> element. Second, binding name is not propagated into WSDL properly when the same binding is used in two or more endpoints (in this example http://localhost:666/TransferService.svc/ and http://localhost:666/TransferService.svc/securereliableMTOM endpoints are bound to Default binding. If you look closely into the generated WSDL, you will see that the matching WSDL ports are not named after bindingName attribute.

These are non-breaking issues and will probably be addressed for beta 2 of WCF.

In the next Indigo series post, we’ll look closely into the security characteristics of certificate based authentication.

Categories:  .NET 3.0 - WCF | Transactions | Web Services
Friday, August 12, 2005 12:02:47 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Indigo CTP 

Microsoft “Indigo” is now available for general public.

If you are an MSDN Subscriber, you can download the bits from here.

Categories:  Web Services | Work | XML
Sunday, March 20, 2005 6:34:26 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 SCT in WSE2 and WS-SecureConversation 

If you get this error [1], while working on a WS-SecureConversation based application, consider the following:

  • Look at the timeout period for you SCTs, issued by the server-side service.
  • If this is all ok, then you're probably in my situation. Check if you enabled web garden support in your IIS's application pool. If so, go back to Performance tab in application pool's properties and enter 1 (one) as a 'Maximum number of worker processes'.

Things can get really rough in a state WSE2 is in if you create a web garden and use WS-SecureConversation at the same time.

A few weeks ago I was designing an architecture for a complex B2B secure communication channel and parts of it wanted to use some form of a web garden. Since I forgot to disable it, there were trouble.

The strangest thing I noticed when investigating this was that everything worked the first time after IIS restart happened - sure - a session is pinned to the first worker process, the second one just gets created.

Of course, there are workarounds regarding this, but they include some non-trivial WSE2 subclassing.

[1] Additional information: Microsoft.Web.Services2.Security.SecurityFault: The specified source for the derivation is unknown ---> System.Exception: WSE512: This derived key token's parent cannot be found. The reference to the parent token follows: <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:Reference URI="uuid:227d47ac-1b2b-45a5-92f0-d7d630aeda86" ValueType="http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct" /></wsse:SecurityTokenReference>.

Categories:  Web Services | Work
Tuesday, October 26, 2004 12:56:29 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 New WS-* and Related Specs 

Lots of new stuff happening lately:

Lots of (un)pleasant reading coming up.

Categories:  Web Services
Thursday, September 16, 2004 10:38:34 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WS-Eventing: SQL Persistance Provider 

Update: Memory persistance included

In my previous posts I said I will write a SQL based persistence provider for Plumbwork.Orange WS-Eventing implementation and help John Bristowe a bit.

It's done now, as is memory based persistance option, but since http://www.gotdotnet.com still has problems with workspaces, I cannot upload it.

Classes can be downloaded here:

All you need to do is replace one line in SubscriptionManagerFactory.cs:

return new XmlSubscriptionManager() as ISubscriptionManager;

With:

return new SqlSubscriptionManager() as ISubscriptionManager;

or

return new MemorySubscriptionManager() as ISubscriptionManager;

Since some members of the workspace are already working on configuration application block integration, all config data should go in there someday.

My implementation now uses SQL Server as a subscription storage for durable WS-Eventing subscriptions. System.Collections.Hashtable is used in memory based persistance model. Complete support includes:

  • Creating a subscription
  • Removing a subscription
  • Renewing a subscription
  • Expiring a subscription

When GDN Workspaces come back online, I will post this to Plumbwork.Orange.

Categories:  Web Services | XML
Friday, August 27, 2004 10:48:47 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WS-Eventing 

John writes:

I'm thankful Matevz didn't blast me for my über-crappy persistance model (read "save to C:\subscriptions.xml"):

Give LOCAL SERVICE account permissions to write/modify the c:\ directory. By default Plumbwork.Orange.Eventing.dll will write subscriptions file (called subscriptions.xml) there.

This line (above) - due to my extreme laziness while coding - makes me shudder. This is something I really, really, really need to clean up.

[Via http://www.bristowe.com]

I agree that next version should include a config option to use Plumbwork.Orange.Eventing.MemorySubscriptionManager instead of Plumbwork.Orange.Eventing.XmlSubscriptionManager.

Even better would be to add SqlSubscriptionManager, which I can do, when I get into the GDN workspace.

Categories:  Web Services | Work | XML
Tuesday, August 24, 2004 9:11:21 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WS-Eventing Implementation 

WS-Eventing Application

It took me half of today to implement a WS-Eventing based service, together with service control application and demonstration client.

I took Plumbwork.Orange implementation of WS-Eventing stack. It includes WSE 2.0 based implementation of WS-Eventing specification, written by John Bristowe. Latest post about updates can be found here.

How it works

Windows service queries message queue (MSMQ) after the period elapses. If it finds any messages, they are dispatched to all registered clients.

There is a service control application, which can enroll new messages into the queue.

There's also a simple client which you can use to register and receive notifications.

Availability

You can download the bits from here:

  • Installer package for WS-Eventing windows service, which does registrations and sends notifications back. Grab it here. Source is available here.
  • Source code, which you can use to compile the service control application. Grab it here.
  • Source code, which you can use to compile the WS-Eventing client. Grab it here.

Do the following:

  • Install WS-Eventing service.
  • Update WSEventingService.exe.config with desired endpoint address, MSMQ query period and queue name
  • Give LOCAL SERVICE account permissions to write/modify the c:\ directory. By default Plumbwork.Orange.Eventing.dll will write subscriptions file (called subscriptions.xml) there.
  • Start the service using SCM (Service Control Manager). Service will automatically create the specified queue. Note: You should have Message Queuing installed.
  • Start the service control application.
  • Start the client. It will register automatically.
  • Send notification using the service control application and watch it emerge on the client side.

If you get into trouble, please email me. Have fun!

Categories:  Web Services | Work | XML
Sunday, August 22, 2004 10:49:46 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Services <> Web Services 

A great post by Clemens in which he does a beautiful distinction between services and web services.

My thoughts would be:

  • Service is a self consistent piece of software which MAY use one or more web services for communication with the outside world.
  • As always, web services MUST be considered to be within the presentation layer of the solution. They just do not spit HTML out, they prefer XML.

MAY and MUST are to be interpreted as defined in RFC 2119.

Categories:  Web Services | XML
Wednesday, August 18, 2004 1:06:45 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WSE 2.0 Router 

How simple is it to implement WS-Addressing based router using WSE (Web Services Enhancements) 2.0?

Try this:

  1. Add the following to a vanilla web.config:
         <system.web>
            <httpHandlers>
                <add verb="*" path="*.asmx"
    type="Microsoft.Web.Services2.Messaging.SoapHttpRouter, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
            </httpHandlers>
         </system.web>
  2. Add this too:
         <microsoft.web.services2>
            <referral>
                <cache name="referralCache.config" />
            </referral>
         </microsoft.web.services2>
  3. Create a referral cache file (save as referralCache.config):
    <?xml version="1.0" ?>
    <r:referrals xmlns:r="http://schemas.xmlsoap.org/ws/2001/10/referral">
      <r:ref>
        <r:for>
          <r:exact><!-- SOURCE URI --></r:exact>
        </r:for>
        <r:if />
        <r:go>
          <r:via><!-- DESTINATION URI --></r:via>
        </r:go>
        <r:refId>uuid:fa468856-0057-4e11-962a-81c5e292f2ae</r:refId>
      </r:ref>
    </r:referrals>
  4. Allow NETWORK SERVICE account write access to referral cache file.
  5. Create an ASP .NET application out of this VRoot.

All SOAP requests sent to your source URI will be redirected to your destination URI. You should be careful to add SoapActor attribute with the appropriate actor URI to your destination service.

Your referral cache file is locked from the moment of first SOAP request, so changing it is impossible without shutting down IIS (or at least the app pool which is serving it).

It is possible and advised that when changing URIs you create another referral cache file and change web.config's microsoft.web.services2/referral/cache element.

Categories:  Web Services
Monday, August 16, 2004 8:52:58 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 OTS 2004 

As last year, I spoke on OTS 2004 too.

This time, we discussed transactional semantics in weakly bound, distributed systems.

Hope to see you on 2005's annual reincarnation of a great conference.

Categories:  Transactions | Web Services | Work
Sunday, June 20, 2004 10:19:39 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WSE 2.0 Out of the Closet 

Finally! After 30 minutes of SteveB's keynote talk, here at TechEd 2004 in San Diego, WSE 2 was announced.

Download it here.

Categories:  Web Services
Monday, May 24, 2004 5:56:15 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 What happened? 

Harwey said it's code complete around March 1st.

As I got the confirmation today that first bits from the Indigo team will be available to the selected ones in late July/early August, this is definitely something to look for.

Why...

Why is...

Why is it...

Why is it still...

Why is it still brewing?

Categories:  Web Services | XML
Monday, May 17, 2004 6:29:13 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WSE 2.0 is finished, alias code complete 

Well, it's not released yet, but good things come last.

WSE (Web Services Enhancements) 2.0 is in mostly done, mostly finished or code complete.

This one is on my most wanted list.

Categories:  Web Services
Wednesday, March 03, 2004 9:51:27 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 IIS horror story 

During preparation for a work presentation for a complex project (designing transport level secure, distributed, endpoint independent web services) I needed to install some benign certificates to an IIS 6 machine. All hell broke lose when I did it and (production) machine failed completely. IIS Admin service would not start, UDDI Services went down, nothing worked.

After numerous hours of trying to fix at least IIS I got an idea of what was wrong.

Apperently the MachineKeys folder, which holds machine account private keys was screwed. No matter how hard I tried reinstalling IIS nothing worked. The solution was in manually deleting MachineKeys folder, encrypting it and setting appropriate permission set.

So, if you are ever in a situation where IIS Admin service would not start causing one of the following errors and you suspect MachineKeys is the reason for it, consider the steps below:

  • The system cannot find the file specified.
  • The handle is invalid.
  • Not enough storage is available to process this command.

Try this:

  • Uninstall IIS
  • Backup files in MachineKeys folder (c:\documents and settings\all users\application data\microsoft\crypto\rsa\machinekeys)
  • Delete MachineKeys folder
  • Create new MachineKeys folder
  • Assign Administrators group, SYSTEM account full permissions
  • ENCRYPT THE DAMN FOLDER (Properties, Encryption)
  • Copy keys if necessary
  • Reinstall IIS

Good luck.

Categories:  Personal | Web Services
Tuesday, March 02, 2004 9:59:25 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 DevDays start 

What happened with Clemens?

It was a nice show (I watched via live Webcast), but someone was missing. :)

Categories:  Web Services
Thursday, January 22, 2004 7:08:57 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WSDL misconceptions 

Well, until today (and I don't know why) I had a concept in my head, that WSDL operation names need to be unique.

I'm really glad that guys from a big local mobile operator helped me clear things up (actually, they helped me lead myself into a no-exit alley). It happened today, during my web services day, a part of a bigger .NET training course.

I reread the spec. It says:

Since operation names are not required to be unique (for example, in the case of overloading of method names), the name attribute in the operation binding element might not be enough to uniquely identify an operation. In that case, the correct operation should be identified by providing the name attributes of the corresponding wsdl:input and wsdl:output elements.

Polymorphic methods are my friends again. I was mislead about the WSDL serialization details in that scenario.

Enough said.

Categories:  Web Services
Thursday, January 15, 2004 9:48:40 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Christian is not the only freak 

Christian Weyer admits he's not the only one thinking that SoapScope is that great.

My priorities go like this:

  1. Excellent Testing Tool
  2. BP 1.0 Complience Verifier
  3. Great VS Integration

Keep it up.

Categories:  Web Services
Saturday, January 10, 2004 8:24:15 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 SoapScope 3.0 Released 

It happened. Mindreef released a new version of its excellent tool - SoapScope 3.0.

Web services diagnostics has never been so efficient.

Categories:  Web Services
Saturday, January 10, 2004 10:41:34 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Hosting Indigo services 

Proof:

Steps to reproduce:

  1. Install Longhorn
  2. Install Longhorn SDK
  3. Install IIS 7.0
  4. Do a aspnet_regiis.exe -i to install ASP .NET and enable it in IIS manager

Default wire level format of the request is (WS-Addressing goop present):

<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:env="
http://www.w3.org/2001/12/soap-envelope">
 <env:Header>
  <wsa:Action xmlns:wsa="
http://schemas.xmlsoap.org/ws/2002/12/addressing">http://www.tempuri.org/quickstarts/hosting/client</wsa:Action>
  <wsa:MessageId xmlns:wsa="
http://schemas.xmlsoap.org/ws/2002/12/addressing">uuid:eddab546-ff51-491f-805a-c497c8918543;id=1</wsa:MessageId>
  <wsa:To env:mustUnderstand="true" xmlns:wsa="
http://schemas.xmlsoap.org/ws/2002/12/addressing">http://bit:6666/webservices/hello/hello.msgx</wsa:To>
  <wsa:ReplyInfo xmlns:wsa="
http://schemas.xmlsoap.org/ws/2002/12/addressing">
   <wsa:To env:mustUnderstand="true">uuid:6572af77-a988-4e80-8bd2-59d036139ae4;id=1</wsa:To>
  </wsa:ReplyInfo>
  <wsa:Path env:mustUnderstand="true" env:role="
http://www.w3.org/2002/12/soap-envelope/role/next"
   xmlns:wsa="
http://schemas.xmlsoap.org/ws/2002/12/addressing">
   <wsa:Request>
    <wsa:Forward>
     <wsa:Via wsa:Role="
http://bit:6666/webservices/hello/hello.msgx" />
    </wsa:Forward>
    <wsa:Reverse>
     <wsa:Via />
    </wsa:Reverse>
   </wsa:Request>
  </wsa:Path>
 </env:Header>
 <env:Body>
  <Root d3p1:type="d3p2:String" xmlns:d3p2="
http://tempuri.org/System" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="
http://schemas.microsoft.com/serialization/2003/02/DefaultDocumentElement">Aaaa!</Root>
 </env:Body>
</env:Envelope>

Categories:  Web Services
Thursday, November 27, 2003 9:58:48 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 WSE on Windows Server 2003 

Can't get one of my solutions to work on a Windows Server 2003 based server. Client works fine, but server side X509-based decryption fails with an error that should not happen (Cannot find the certificate and private key for decrtyption).

Everything installed and correctly setup. Even permissions. :)

Since even the official Microsoft newsgroup didn't help, I'm really stuck. The funny thing is, that if I disallow access to private key and/or remove the certificate, error message changes giving me a clue that WSE looks at the cert unsuccessfully.

Categories:  Web Services | XML
Wednesday, November 26, 2003 2:32:11 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 VRoots Changed 

Since I went through a main server reinstall I also moved my sub-sites to new domain names. Lupus is now listening on http://lupus.request-response.com and my little playground page is located on http://playground.request-response.com.

Redirects from http://www.request-response.com/lupus and http://www.request-response.com/playground are not available and will probably never be. If anyone has a permanent endpoint on RSS Query web service, she will know soon. ;)

Categories:  Personal | Web Services
Sunday, November 09, 2003 1:55:12 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 .NET != Web Services 

Eric Maino writes about an obvious example of misleading writing on this Microsoft page.

I tend to agree. What should also be emphasized is that Web Services are not the only core feature of .NET. There's more meat behind the curtain.

Categories:  Web Services | Other
Tuesday, October 14, 2003 9:35:06 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 UDDI level 2 status 

After numerous unsuccessful attempts to contact the Microsoft UDDI team I emailed Karsten Januszewski directly and he managed to get it fixed in less than a day. Thanks Karsten!

We are now at level 2, so we can publish whatever we want. Currently we have seven services and this weblog registered.

What's interesting is that the UDDI categorization scheme seems to have changed. One can now do a successful search in InfoPath/VS.NET only if a service is assigned to wsdlSpec category.

Categories:  Web Services
Tuesday, October 14, 2003 9:26:06 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 UDDI level 2 status 

We are unsuccessful with our emails to Microsoft UDDI team to upgrade our UDDI account to level 2 status. If anyone knows an appropriate contact or is able to help directly, please do so.

UDDI Provider name: Gama System
Current UDDI level: 1

Categories:  Web Services | Work | XML
Saturday, October 04, 2003 1:54:35 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Mono web services 

Latest daily build of Mono already allows web service proxy creation, compilation and execution. I had to manually compile the wsdl.exe equivalent (called MonoWSDL.exe) and then do:

  • mono MonoWSDL.exe http://www.gama-system.com/webservices/stockquotes.asmx?wsdl (outputs StockQuotes.cs proxy)
  • mcs /r:/usr/local/lib/System.Web.Services.dll /t:library StockQuotes.cs
  • write a simple console web service client app (StockQuotesClient.cs)
  • compile it using mcs /r:StockQuotes.dll StockQuotesClient.cs
  • run it with mono StockQuotesClient.exe NASDAQ MSFT

What did I get?

This:

That's sweet. But Mono can now also do it the other way around. I can generate proxies on our platform using the standard wsdl.exe tool. Mono web services test page looks like this:

When one adds the "?wsdl" suffix to a web service endpoint WSDL is returned as expected.

I like it.

[Note: http://www.gama-system.com/webservices/stockquotes.asmx is our free stock ticker web service]

Categories:  XML | Web Services | Mono
Saturday, September 13, 2003 12:29:49 AM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Microsoft.com Web Services 

Here's my implementation of Microsoft.com Web Services client: http://www.request-response.com/playground/mscomws.

It's done manually:

  1. Create SOAP Request
  2. Get response
  3. Scrape through response using XSLT
  4. Generate HTML, using XSLT's for-each, value-of, concat, substring-before, ...
  5. Insert HTML into .aspx page
Categories:  XML | Web Services
Saturday, September 06, 2003 9:13:21 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Microsoft.com Web Services SDK 
This is good. Now people can automaticaly download new Microsoft software, articles, Technet content, ...

In order to serve as a test for our new architecture, Version 1.0 of the Microsoft.com Web Service is limited to providing information about top downloads from Microsoft.com. Future releases will build on this architecture to provide access to a broader variety of Microsoft content and services.

This is not so good. Should be called v0.31 then.
Categories:  Web Services
Wednesday, August 27, 2003 2:02:59 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Web services subpage redesigned 

We just did a redesign on our /webservices subsection. You can find info/downloads/functions/... on it. Everything is free to use - some contents are applicable only to local users, though.

URL: http://www.gama-system.com/webservices

Categories:  Work | Web Services
Tuesday, August 26, 2003 6:35:44 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Mono web services 

I managed to get web services up and running on my Mono machine. This proves it.

What I dislike about the current implementation is obvious:

  • There's no WSDL generator yet (can't use wsdl.exe or any other web services proxy generator tools)
  • There's no proxy class generator yet (wsdl.exe in our world)
  • URLs seem to be case sensitive

My install uses the latest Mono bits and a primitive web server (XSP), which hosts the Mono ASP.NET runtime.

I tested this stuff using WebServicesStudio, which can generate proxies and SOAP messages. I used .NET web service implementation to generate the proxy and then sent SOAP messages to Mono implementation.

All in all, I'm quite surprised. Mono's latest development advances are a huge step forward.

Categories:  Web Services
Sunday, August 03, 2003 2:29:18 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 A mess 

It seems that it is that time of year again. Sun started another web services attack by releasing competing stack of standards.

Eventually we will drown in web services specs. History is evidently repeating itself. We're going down the COM/CORBA route.

Categories:  Web Services
Monday, July 28, 2003 8:16:24 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 Querying RSS URLs on UDDI 

Based on this and this I just wrote a web service, which enables RSS URL lookup for web logs registered at UDDI.

It should be simple to integrate this into current RSS aggregators. Email me for code.

Web service URL: http://www.request-response.com/webservices/rssquery/rssquery.asmx

There are two metods. One returns an RSS URL based on UDDI service key. One returns an RSS URL based on UDDI service name. If multiple versions of RSS feeds are found, service looks for RSS 2.0 feed first. Then RSS 1.0, then RSS 0.9x. It returns '-1' if no feed is found.

Web service does dynamic queries against Microsoft's UDDI server inquire API.

Categories:  RSS | Web Services | XML
Thursday, July 24, 2003 3:45:33 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 The list (continued) 

Clemens updates his OPML list.

For those of you who thought his web site isn't working, here's a hint: Wait.

Errr, no more waiting (courtesy of .NET threading model and Clemens).

When is Greg going to include this one into the product I'm using right now? It would be great if it got into version 1.3 feature list.

Categories:  RSS | Web Services
Thursday, July 24, 2003 12:45:00 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

 UDDI team responds 

Via email:

Thank you for contacting Microsoft.com. 
We have forwarded your mail to the appropriate Microsoft group for further review.  Additional information may be required to assist you.

By taking the time to write, you are helping us provide the best possible products and services.

Thanks again!

Ampee
Microsoft.com Customer Support

Glad to be of any help. I just want to get UDDI level 2 status. We have more than four services, which we would like to register. InfoPath demos would go through much smoother...

[Note: Who/What is Ampee?]

Categories:  Web Services
Wednesday, July 23, 2003 3:57:04 PM (Central Europe Standard Time, UTC+01:00)  #    Comments

 

Copyright © 2003-2014 , Matevž Gačnik
Recent Posts
RD / MVP
Feeds
RSS: Atom:
Archives
Categories
Blogroll
Legal

The opinions expressed herein are my own personal opinions and do not represent my company's view in any way.

My views often change.

This blog is just a collection of bytes.

Copyright © 2003-2014
Matevž Gačnik

Send mail to the author(s) E-mail