Tuesday, 23 December 2008

Hi all

At Logica we often participate in different events where employees compete to see who rides their bike more often to work, who walks the most steps in a month, and so on. After a month of competition, we end up with a spreadsheet, where I may have walked 180.000 steps, but my colleague Henrik only walked 78.000 steps (He is kind of a wimp :-) )

So lets say that we want to give a prize to one of us, and Henrik should have a chance of 78000/(78000+180000) (30,23%) of winning and I should have a chance of 180000/(78000+180000) (69,77%) of winning. As the number of points and the number of contestants get bigger, this becomes increasingly difficult to manage.

Therefore, I have written a small winforms program, that helps you manage this. You can add as many contestants as you like, and give them points. If you are only interested in a "normal" draw, you can just give all contestants one point.

Screen shot:

eliasen.eu.draw.screenshot

The program not only does the draw, it will also:

  • Give you an overview of the contestants, their points and their chance of winning, which is dynamically updated each time a contestant is added
  • Give you the opportunity to simulate any number of draws, to ensure that the program is random. When doing the simulation, the percentage of wins by each contestant is shown next to the chance of winning, so they can be compared.

I will gladly take comments, bug reports, suggestions, postcards, et cetera :-)

The documentation can be found at http://www.eliasen.eu/DownloadSoftware.aspx#documentation and the program can be downloaded at http://www.eliasen.eu/DownloadSoftware.aspx#winform.

I hope this comes in handy to someone.

--
eliasen

Tuesday, 23 December 2008 21:27:44 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Hi all

I am using http://www.last.fm to keep track of what I listen to, and to get inspired to listen to some new music that I didn't know I liked.

You can find my profile at http://www.last.fm/user/eliasen and you can find information about an excellent Danish band Baal at http://www.last.fm/music/Baal. Please note, though, that I listen to the Danish band Baal, and not the Japanese band that unfortunately shares the band name Baal with the Danish band.

Anyway, the point of this blog post is, that it seems that I am currently the top listener of Baal:

baal_top_listener

:-)

This means that I listen to more Baal than all that listen to either the Danish or the Japanese band...

I know... Get a life, damn it! :-)

Baal have a web site at http://www.baalworld.com - try it! :-)

--
eliasen

Tuesday, 23 December 2008 21:27:19 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Hi all

It is time for the third posting in my series about using BizTalk to integrate to Excel spreadsheets. My first two postings are here (Installation) and here (The schema generation wizard).

This third posting is a talk about the runtime, and how it works.

The setup

To start out, I have done a simple test, and you can find my project

.

It has a simple spreadsheet and a schema for this spreadsheet (both are described in my previous post) and the setup basically just has a FILE Receive Location and a send port with a filter that takes everything from the Receive Port the Receive Location belongs to. My aim is to see how fast the Spread Disassembler is.

First, a short description of my setup:

My BizTalk installation is in a Microsoft Virtual PC 2007 virtual machine.

The host machine is a Hewlett Packard 8710w laptop with an Intel Core Duo T7700 2,4GHz CPU, 2GB of RAM and Windows XP Professional Service Pack 3 and completely updated as of 7'th December 2008.

The guest system is a virtual machine which has one 2,4GHz CPU, 1GB RAM and Microsoft Windows Server 2003 R2 Enterprise Edition SP2 - also completely updated as of 7'th December 2008.

The test

I created 999 copies of the same spreadsheet and moved them into a folder watched by the receive location. They were read, transformed into XML, and output into the output folder in 3:19 minutes. This is an average of 5 spreadsheets per second.

This took me by surprise - I had expected it to be faster. So I decided to do things more academic than looking at the time stamps of the output files. After all, there are PLENTY of functionality that could be the time consumer. So I created a BAM Activity and View, tracking when my Receive Port starts and when it ends.

A table showing the average processing time can be seen here:

Number of messages in test Average processing time per message Messages per minute
5 0,0227 seconds 2643
63 0,0337 seconds 1780
127 0,0584 seconds 1027
1966 0,2714 221

So it is pretty clear, that performance drops drastically when the load increases. I do not blame this on the Spread Disassembler, though. Since this is a virtual PC, with SQL Server on the same box as BizTalk, the mere I/O operations when writing all the output files to the hard drive conflicts with the I/O operations of BizTalk using the MessageBox. I find this a much more likely issue for the drop in performance than that the disassembler should get slower just because more messages come in.

So, to sum up, it seems that the Spread Disassembler can take a pretty heavy load - Up to 2643 messages per minute (44 messages per second). This is given less than ideal operating and hardware conditions, but optimal conditions with regards to the BizTalk Server not doing anything else at the time.

Maybe in a later post I will take a look at more complex spreadsheets/schemas and also test the performance of the assembler.

--
eliasen

Tuesday, 23 December 2008 21:26:40 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 

Hi all

The company hosting the eliasen.dk domain went bancrupt last friday (19'th December 2008), and I only just found out this morning (Monday the 22'nd December).

So basically, everything since my last backup (27'th November 2008) is gone!

Right now, I am trying to setup the blog on the new server and trying to see if I can repost the blog posts I have written since the 27'th November.

--
eliasen

Tuesday, 23 December 2008 21:23:30 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Thursday, 27 November 2008

Hi all

A new functoid has been added to the collection of functoids that an be downloaded at http://www.eliasen.eu/Downloadsoftware.aspx.

The functoid simply takes one parameter, which is used as a key against BizTalks app.config (The BTSNTSvc.exe.config file in BizTalks installation folder) to read an application setting from the appSettings group.

So given a .config file like this:

<appSettings>
<add key="eliasen" value="eliasenValue" />
</appSettings>

and the parameter "eliasen" to the functoid, it will return "eliasenValue". If the key cannot be found, an empty string is returned.

And the documentation has also been updated - look at http://www.eliasen.eu/DownloadSoftware.aspx

--
eliasen

Thursday, 27 November 2008 21:20:03 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Monday, 24 November 2008

Hi all

I have added a new functoid to my functoid library.

This functoid will take a string, that is separated by some character as input and split it up into the substrings it is, given the separator. It will then return the substring given by a third parameter.

So for instance, given these three inputs:

  1. Jan,Eliasen,BizTalk
  2. ,
  3. 1

You would get "Eliasen" as output.

You can download my functoid library at http://www.eliasen.eu/DownloadSoftware.aspx and here you can also find updated documentation describing this new functoid.

--
eliasen

Monday, 24 November 2008 02:06:33 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Saturday, 22 November 2008

Hi all

As you have probably read in my previous posts this month, I have started creating a functoid library, which is freely downloadable if you want to. Now, I have also written some documentation for it (Wauv, I know...). So go to http://www.eliasen.eu/DownloadSoftware.aspx for the software, and here you can find a link to http://www.eliasen.eu/files/eliasen.eu.documentation.docx which contains the documentation for the downloadable software.

--
eliasen

Saturday, 22 November 2008 00:03:14 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Thursday, 20 November 2008

Hi all

I have added a new functoid to the collection of functoids I am building. This time, I have programmed a functoid that converts between different datetime formats, which comes in handy when mapping between two schemas that have date elements, that require different formats of the date.

You can find version 4 of my functoid collection at http://www.eliasen.eu/DownloadSoftware.aspx

--
eliasen

Thursday, 20 November 2008 00:41:07 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Wednesday, 19 November 2008

Hi all

Recently, I started using Windows Live Writer in large scale. Until then, I used the built in editing functionality of dasBlog, which is my blog software.

I must say, I love it!

Now, don't get me wrong, I have no other software products that do what Windows Live Writer does to compare it with, so there might be other and better products out there, but I am SO happy with not using the built in functionality of dasBlog anymore, I just had to tell you all :-)

The obvious advantages for using Windows Live Writer over the built in functionality in dasBlog are the possibility to work offline, either if my blog is unavailable or if I am in a train, and so on.

But also, I am quite fond of the way I can have multiple entries as work in progress at the same time, edit existing posts, etc. And all in a thick client on my laptop.

Really, I am quite thrilled :-) And I encourage all to use it... There is a newer version out than the 2008 that I am using, but it is a beta version, and some people have reported issues with using it against dasBlog, so I will wait a bit before I try that version.

--
eliasen

Wednesday, 19 November 2008 22:37:11 (Romance Standard Time, UTC+01:00)  #    Comments [0]  | 
Tuesday, 18 November 2008

Hi all

This is the second post in a series about solving the "If-Then-Else" problem in a map. In my first post I discussed how to use BizTalks built-in functionality to solve the problem. Neither of the three proposed solutions really seem nice to me, so I wondered how difficult it might be to code a custom functoid that does the trick. It turned out to be unexpectedly hard, and this post tries to clarify my findings and explain them.

So, to continue from my previous post, to me the best solution is to code your own functoid, that mimics the value mapping functoid, but adds an "else" part. So basically just a third parameter to the value  mapping functoid that is returned in case the first parameter is false.

For information about how to program a custom functoid, please visit http://msdn.microsoft.com/en-us/library/aa560879.aspx - I wont go into details about that here. I will just comment on the issues I have had with creating this particular functoid.

The final solution should give me the possibility to have a map like this one:

IfThenElseCustomFunctoid

YES, I know my icons are very bad... Anyway, three inputs: a boolean and two values.

So, getting to the code, my first try looked like this:

-- BEGIN CODE
this.SetMinParams(3);
this.SetMaxParams(3);
this.Category = FunctoidCategory.ValueMapping;
this.OutputConnectionType = ConnectionType.AllExceptRecord;
AddInputConnectionType(ConnectionType.AllExceptRecord);
AddInputConnectionType(ConnectionType.AllExceptRecord);
AddInputConnectionType(ConnectionType.AllExceptRecord);
-- END CODE

I have removed irrelevant lines, such as setting up the resources, setting the ID, and so on.

First of all, in the code of a custom functoid, you need to specify which category the functoid should belong to. The possibilities are listed at http://msdn.microsoft.com/en-us/library/microsoft.biztalk.basefunctoids.functoidcategory.aspx. I hadn't really looked at this list, since I thought that the intellisense in VS.NET 2005 was good enough. Since my functoid is an advanced value mapping functoid, I chose he value mapping category. This turned out a but different than I thought. It turns out, that the category you assign to a custom functoid not only determines where in the toolbox it should be placed, but also sometimes some extra functionality is added to the functoid. Given my map above, I had expected that the created XSLT would just call my functoid with the three parameters and then my code would do the rest. But the generated XSLT looks like this:

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0 userCSharp" version="1.0" xmlns:s0="http://eliasen.eu.BizTalk.TestProject.InputSchema" xmlns:ns0="http://eliasen.eu.BizTalk.TestProject.OutputSchema" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="/">
    <xsl:apply-templates select="/s0:InputRoot" />
  </xsl:template>
  <xsl:template match="/s0:InputRoot">
    <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(qualifier/text()) , &quot;Jan&quot;)" />
    <ns0:OutputRoot>
      <xsl:if test="string($var:v1)='true'">
        <xsl:variable name="var:v2" select="IfTrue/text()" />
        <OutputField>
          <xsl:value-of select="$var:v2" />
        </OutputField>
      </xsl:if>
    </ns0:OutputRoot>
  </xsl:template>
</xsl:stylesheet>

I have removed all the lines associated with the equals-functoid as that included three inline c# methods which are irrelevant. Anyway, as you can see, my functoid is not being called at all. Because I chose the ValueMapping category, the generated xslt assumes it is actually a built-in value mapping functoid and it totally overrules the logic inside the functoid.

So, this really came as a surprise to me... but well...it makes sense when you think about it, naturally. Some of the types of functoids just require logic that goes beyond the code inside a functoid.

So, the ValueMapping category just didn't work for me. Then I thought; "Oh, who cares?"? I will just use the String category instead, because those certainly do not have weird functionality around them... they get input and return a string as output, that is it. And the functoid will just appear in the String group in the toolbox in VS.NET.

That gave me a new headache, that was another surprise; You cannot connect the output of a logical functoid to the input of a string functoid. So... I was stuck.

One of my solutions would accept the output of a logical functoid as input, but my functoid logic was overridden. The other simply wouldn't accept the output of a logical functoid as input.

I have tried the following FunctoidCategories:

Category Description
Assert Terminates when logical functoid returns true. Has the wrong value in output field when logical functoid returns false.
Conversion Cannot connect output of logical functoid to input.
Count Cannot connect output of logical functoid to input.
Cumulative Cannot connect output of logical functoid to input.
DatabaseExtract Cannot connect output of logical functoid to input.
DatabaseLookup Cannot connect output of logical functoid to input.
DateTime Cannot connect output of logical functoid to input.
ExitenceLooping Cannot connect output of logical functoid to input.
Index Cannot connect output of logical functoid to input.
Iteration Cannot connect output of logical functoid to input.
Keymatch Cannot compile. You get an "Object not set to an instance of an object" exception.
Logical The output field isn't created.
Looping Cannot connect output of logical functoid to input.
MassCopy Cannot connect output of logical functoid to input.
Math Cannot connect output of logical functoid to input.
NilValue Only creates output field if logical functoid returns true and then it adds the xsi:nil attribute and no value in the output field.
Scientific Cannot connect output of logical functoid to input.
Scripter The scripting functoid has no script type set, either external or inline, so proper code cannot be generated for it.
String Cannot connect output of logical functoid to input.
TableExtractor Cannot connect output of logical functoid to input.
TableLooping Needs the table grid configured and is therefore useless.
Unknown Cannot connect output of logical functoid to input.
ValueMapping Only creates the output field if the logical functoid returns true.
XPath Cannot connect output of logical functoid to input.

So, basically, I haven't been able to do it... for now. Either I cannot connect a logical functoid to my custom functoid, I get an error either at compile time or something goes wrong semantically at runtime.

I haven't given up 100% yet... but I must say, that the task has turned out to be a whole lot more difficult than I thought it would be.

Look out for a part 3 in this series... if it comes, I will have solved this issue :-)

--
eliasen

Tuesday, 18 November 2008 01:01:32 (Romance Standard Time, UTC+01:00)  #    Comments [1]  | 

Theme design by Jelle Druyts