Author: Richard Seroter

  • I’m Heading to Sweden to Deliver a 2-Day Workshop

    The incomparable Mikael Håkansson has just published the details of my next visit to Sweden this September. After I told Mikael about my latest book, we thought it might be epic to put together a 2 day workshop that highlights the “when to use what” discussion.  Two of my co-authors, Stephen Thomas and Ewan Fairweather, will be joining me for busy couple of days at the Microsoft Sweden office.  This is the first time that Stephen and Ewan have seen my agenda, so, surprise guys!

    We plan to summarize each core technology in the Microsoft application platform and then dig into six of the patterns that we discuss in the book.  I hope this is a great way to introduce a broad audience to the nuances of each technology and have a spirited discussion of how to choose the best tool for a given situation.

    If other user groups would be interested in us repeating this session, let me know.  We take payment in the form of plane tickets, puppies or gold bullion.

    Share

  • Impact of Namespace Style Choice on BizTalk Components

    I could make up a statistic that says “83% of all BizTalk schemas use the namespace automatically assigned to it” and probably not be wildly off.  That said, I wondered if BizTalk handled all the different namespace styles in the same way.  Specifically, does BizTalk care if we use schemas with traditional “URL-style” namespaces, URN namespaces, single value namespaces, and empty namespaces?  Short answer: it doesn’t matter.

    I suspect that many XSD designers currently go with a URL-based approach like so:

    2010.06.10ns01

    However, you could also prefer to go with a Uniform Resource Name style like this:

    2010.06.10ns02

    You might also choose to do something easier for you to understand, which might be a single identifier.  For instance, you could just use a namespace called “Enterprise” for company wide schemas, or “Vendor” for all external partner formats.

    2010.06.10ns03

    Finally, you may say “forget it” and not use a namespace at all.

    2010.06.10ns04

    The first thing I tested was simple routing.  The subscription for a URN-style message looked like this:

    2010.06.10ns05

    The “single value” format subscription looks like this:

    2010.06.10ns06

    Finally, if you have no namespace at all on your schema, the message subscription could look like this:

    2010.06.10ns07

    In that case, all you have is the root node name.  After testing each routing scenario, as you might expect, they all work perfectly fine.  I threw a property schema onto each schema, and there were no problems routing there either.

    I also tested each schema with the Business Rules Engine and each worked fine as well.

    Moral of the story?  Use a namespace style that works best for your organization, and, put some real thought into it.  For instance, if a system that you have to integrate with can’t do namespaces, don’t worry about changing the problem system since BizTalk can work just fine.

    I didn’t go through all the possible orchestration, mapping and WCF serialization scenarios, but would expect that we’d see similar behavior.  Any other real-life tales of namespaces you wish to share?

    Share

  • Announcing My New Book: Applied Architecture Patterns on the Microsoft Platform

    So my new book is available for pre-order here and I’ve also published our companion website. This is not like any technical book you’ve read before.  Let me back up a bit.

    Last May (2009) I was chatting with Ewan Fairweather of Microsoft and we agreed that with so many different Microsoft platform technologies, it was hard for even the most ambitious architect/developer to know when to use which tool.  A book idea was born.

    Over the summer, Ewan and I started crafting a series of standard architecture patterns that we wanted to figure out which Microsoft tool solved best.  We also started the hunt for a set of co-authors to bring expertise in areas where we were less familiar.  At the end of the summer, Ewan and I had suckered in Stephen Thomas (of BizTalk fame), Mike Sexton (top DB architect at Avanade) and Rama Ramani (Microsoft guy on AppFabric Caching team).   All of us finally pared down our list of patterns to 13 and started off on this adventure.  Packt Publishing eagerly jumped at the book idea and started cracking the whip on the writing phase.

    So what did we write? Our book starts off by briefly explaining the core technologies in the Microsoft application platform including Windows Workflow Foundation, Windows Communication Foundation, BizTalk Server, SQL Server (SSIS and Service Broker), Windows Server AppFabric, Windows Azure Platform and StreamInsight.  After these “primer” chapters, we have a discussion about our Decision Framework that contains our organized approach to assessing technology fit to a given problem area.  We then jump into our Pattern chapters where we first give you a real world use case, discuss the pattern that would solve the problem, evaluate multiple candidate architectures based on different application technologies, and finally select a winner prior to actually building the “winning” solution.

    In this book you’ll find discussion and deep demonstration of all the key parts of the Microsoft application platform.  This book isn’t a tutorial on any one technology, but rather,  it’s intended to provide the busy architect/developer/manager/executive with an assessment of the current state of Microsoft’s solution offerings and how to choose the right one to solve your problem.

    This is a different kind of book. I haven’t seen anything like it.  Either you will love it or hate it.  I sincerely hope it’s the former, as we’ve spent over a year trying to write something interesting, had a lot of fun doing it, and hope that energy comes across to the reader.

    So go out there and pre-order, or check out the site that I set up specifically for the book: http://AppliedArchitecturePatterns.com.

    I’ll be sure to let you all know when the book ships!

  • Interview Series: Four Questions With … Dan Rosanova

    Greetings and welcome to the 21st interview in my series of chats with “connected technology” thought leaders.  This month we are sitting down with Dan Rosanova who is a BizTalk MVP, consultant/owner of Nova Enterprise Systems, trainer, regular blogger, and snappy dresser.

    Let’s jump right into our questions!

    Q: You’ve been writing a solid series of posts for CIO.com about best practices for service design and management.  How should architects and developers effectively evangelize service oriented principles with CIO-level staff whose backgrounds may range from unparalleled technologist to weekend warrior?  What are the key points to hit that can be explained well and understood by all?

    A: No matter their background successful CIOs all tend to have one trait I see a lot: they are able to distil a complex issue into simple terms. IT is complex, but the rest of our organizations don’t care, they just want it to work and this is what the CIO hears. Their job is to bridge this gap.

    The focus of evangelism must not be technology, but business. By focusing on business functionality rather than technical implementations we are able to build services that operate on the same taxonomies as the business we serve. This makes the conversation easier and frames the issues in a more persuasive context.

    Service Orientation is ultimately about creating business value more than technical value. Standardization, interoperability, and reuse are all cost savers over time from a technical standpoint, but their real value comes in terms of business operational value and the speed at which enterprises can adapt and change their business processes.

    To create value you must demonstrate

     

    • Interoperability
    • Standardization
    • Operational flexibility
    • Decoupling of business tasks from technical implementation (implementation flexibility)
    • Ability to compose existing business functions together into business processes
    • Options to transition to the Cloud – they love that word and it’s in all the publications they read these days. I am not saying this to be facetious, but to show how services are relevant to the conversations currently taking place about Cloud.

    Q: When you teach one of your BizTalk courses, what are the items that a seasoned .NET developer just “gets” and which topics require you to change the thinking of the students?  Why do you think that is?

    A: Visual Studio Solution structure is something that the students just get right away once shown the right way to do it for BizTalk. Most developers get into BizTalk with single project solutions that really are not ideal for real world implementations and simply never learn better. It’s sort of an ‘ah ha’ moment when they realize why you want to structure solutions in specific ways.

    Event based programming, the publish-subscribe model central to BizTalk, is a big challenge for most developers. It really turns the world they are used to upside down and many have a hard time with it. They often really want to “start at the beginning” when in reality, you need to start at the end, at least in your thought process. This is even worse for developers from a non .NET background. Those who get past this are successful; those who do not tend to think BizTalk is more complicated than the way “they do things”.

    Stream based processing is another one students struggle with at first, which is understandable, but is critical if they are ever to write effective pipeline components. This, more than anything else is probably the main reason BizTalk scales so well. BizTalk has amazing stream classes built into it that really should be open to more of .NET.

    Q: Whenever a new product (or version of a product) gets announced, we all chatter about the features we like the most.  Now that BizTalk Server 2010 has been announced in depth, what features do you think will have the most immediate impact on developers?  On the other hand, if you had your way, which feature would you REMOVE from the BizTalk product?

    A: The new per Host tuning features in 2010 have me pretty jazzed. It is much better to be able to balance performance in a single BizTalk Group rather than having to resort to multiple groups as we often did in the past.

    The mapper improvements will probably have the greatest immediate impact on developers because we can now realistically refactor maps in a pretty easy fashion. After reading your excellent post Using the New BizTalk Mapper Shape in a Windows Workflow Service I definitely feel that a much larger group of developers is about to be exposed to BizTalk.

    About what to take away, this was actually really hard for me to answer because I use just about every single part of the product and either my brain is in sync with the guys who built it, or it’s been shaped a lot by what they built. I think I would take away all the ‘trying to be helpful auto generation’ that is done by many of the tools. I hate how the tools do things like default to exposing an Orchestration in the WCF Publishing Wizard (which I think is a bad idea) or creating an Orchestration with Multi Part Message Types after Add Generated Items (and don’t get me started on schema names). The Adapter Pack goes in the right direction with this and they also allow you to prefix names in some of the artifacts.

    Q [stupid question]: Whenever I visit the grocery store and only purchase a couple items, I wonder if the cashier tries to guess my story.  Picking up cold medicine? “This guy might have swine flu.”  Buying a frozen pizza and a 12-pack of beer? “This guy’s a loner who probably lets his dog kiss him on the mouth.”  Checking out with a half a dozen ears of corn and a tube of lubricant?  “Um, this guy must be in a fraternity.”  Give me 2-4 items that you would purchase at a grocery store just to confuse and intrigue the cashier.

    A: I would have to say nonalcoholic beer and anything. After that maybe caviar and hot dogs would be a close second.

    Thanks Dan for participating and making some good points.

    Share

  • Using the New BizTalk Mapper Shape in a Windows Workflow Service

    So hidden within the plethora of announcements about the BizTalk Server 2010 beta launch was a mention of AppFabric integration.  The best that I can tell, this has to do with some hooks between BizTalk and Windows Workflow.  One of them is pretty darn cool, and I’m going to show it off here.

    In my admittedly limited exposure thus far to Windows Workflow (WF), one thing that jumped out was the relatively clumsy way to copy data between objects.  Now, you get a new “BizTalk Mapper” shape in your Windows Workflow activity palette which lets you use the full power of the (new) BizTalk Mapper from within a WF.

    First off, I created a new .NET 4.0 Workflow Service.  This service accepts bookings into a Pet Hotel and returns a confirmation code.  I created a pair of objects to represent the request and response messages.

    namespace Seroter.Blog.WorkflowServiceXForm
    {
        public class PetBookingRequest
        {
            public string PetName { get; set; }
            public PetList PetType { get; set; }
            public DateTime CheckIn { get; set; }
            public DateTime CheckOut { get; set; }
            public string OwnerFirstName { get; set; }
            public string OwnerLastName {get; set; }
        }
    
        public class PetBookingConfirmation
        {
            public string ConfirmationCode { get; set; }
            public string OwnerName { get; set; }
            public string PetName { get; set; }
        }
    
        public enum PetList
        {
            Dog,
            Cat,
            Fish,
            Barracuda
        }
    }
    

    Then I created WF variables for those objects and associated them with the request and response shapes of the Workflow Service.

    2010.5.24wfmap01

    To show the standard experience (or if you don’t have BizTalk 2010 installed), I’ve put an “Assignment” shape in my workflow to take the “PetName” value from the request message and stick it into the Response message.

    2010.5.24wfmap02

    After compiling and running the service, I invoked it from the WCF Test Client tool.  Sure enough, I can pass in a request object and get back the response with the “PetName” populated.

    2010.5.24wfmap03

    Let’s return to our workflow.  When I installed the BizTalk 2010 beta, I saw a new shape pop up on the Windows Workflow activity palette.  It’s under a “BizTalk” tab name and called “Mapper.”

    2010.5.24wfmap04

    Neato.  When I drag the shape onto my workflow, I’m prompted for the data types of my source and destination message.  I could choose primitive types, or custom types (like I have).

    2010.5.24wfmap05

    After that, I see an unconfigured “Mapper” shape in my workflow. 

    2010.5.24wfmap06

    After setting the explicit names of my source and destination variables in the activity’s Property window, I clicked the “Edit” button of the shape.  I’m asked whether I want to create a new map, or leverage an existing one.

     2010.5.24wfmap07

    This results in a series of files being generated, and a new *.btm file (BizTalk Map) appears.

    2010.5.24wfmap08

    In poking around those XSD files, I saw that two of them were just for base data type definitions, and one of them contained my actual message definition.  What also impressed me was that my code enumeration was properly transferred to an XSD enumeration.

    2010.5.24wfmap09

    Now let’s look at the Mapper itself.  As you’d expect, we get the shiny new Mapper interface included in BizTalk Server 2010.  I’ve got my source data type on the left and destination data type on the right.

    2010.5.24wfmap10

    What’s pretty cool is that besides getting the graphical mapper, I also get access to all the standard BizTalk functoids.  So, I dragged a “Concatenate” functoid onto the map and joined the OwnerLastName and OwnerFirstName and threw it into the OwnerName field.

    2010.5.24wfmap11

    Next, I want to create a confirmation code out of a GUID.  I dragged a “Scripting” functoid onto the map and double clicked.  It’s great that double-clicking now brings up ALL functoid configuration options.  Here, I’ve chosen to embed some C# code (vs. pointing to external assembly or writing custom XSLT) that generates a new GUID and returns it.  Also, notice that I can set “Inline C#” as a default option, AND, import from an external class file.  That’s fantastic since I can write and maintain code elsewhere and simply import it into this limited editor.

    2010.5.24wfmap13

    Finally, I completed my map by connected the PetName nodes.

    2010.5.24wfmap12

    After once again building and running the Workflow Service, I can see that my values get mapped across, and a new GUID shows up as my confirmation value.

    2010.5.24wfmap14

    I gotta be honest, this was REALLY easy.  I’m super impressed with where Windows Workflow is and think that adding the power of the BizTalk Mapper is a killer feature.  What a great way to save time and even get reuse from BizTalk projects, or, aid in the migration of BizTalk solutions to WF ones.

    UPDATE: Apparently this WF activity gets installed when you install the WCF LOB Adpater SDK update for BizTalk Server 2010.  JUST installing BizTalk Server 2010 won’t provide you the activity.

    Share

  • Top 9 Things To Focus On When Learning New Platform Technologies

    Last week I attended the Microsoft Convergence conference in Atlanta, GA where I got a deeper dive into a technology that I’m spending a lot of time with right now.  You could say that Microsoft Dynamics CRM and I are seriously dating and she’s keeping things in my medicine cabinet.

    While sitting in a tips-and-tricks session, I started jotting down a list of things that I should focus on to REALLY understand how to use Dynamics CRM to build a solution.  Microsoft is pitching Dynamics CRM as a multi-purpose platform (labeled xRM) for those looking to build relational database-driven apps that can leverage an the Dynamics CRM UI model, security framework, data structure, etc.

    I realized that my list of platform “to do” things would be virtually identical for ANY technology platform that I was picking up and trying to use efficiently.  Whether BizTalk Server, Force.com, Windows Communication Foundation, Google App Engine, or Amazon AWS Simple Notification Services, a brilliant developer can still get into trouble by not understanding a few core dimensions of the platform.  Just because you’re a .NET rock star it doesn’t mean you could pick up WCF or BizTalk and just start building solutions.

    So, if I were plopping down in front of a new platform and wanted to learn to use it correctly, I’d focus on (in order of importance)  …

    1. Which things are configuration vs. code? To me, this seems like the one that could bite you the most (depending on the platform, of course).  I’d hate to waste a few days coding up a capability that I later discovered was built in, and available with a checkbox.  When do I have to jump into code, and when can I just flip some switches?  For something like Force.com, there are just tons of configuration settings.  If I don’t understand the key configurations and their impact across the platform, I will likely make the solution harder to maintain and less elegant.  WCF has an almost embarrassing number of configurations that I could accidentally skip and end up wasting time writing a redundant service behavior.
    2. What are the core capabilities within the platform? You really need to know what this platform is good at.  What are the critical subsystems and built in functions?  This relates to the previous one, but does it have a security framework, logging, data access?  What should I use/write outside services for, and what is baked right in?  Functionally, what is it great at?  I’d hate to misuse it because I didn’t grasp the core use cases. 
    3. How do I interface with external sources? Hugely important.  I like to know how to share data/logic/services from my platform with another, and how to leverage data/logic/services from another platform into mine. 
    4. When do I plug-in vs. embed?  I like to know when it is smartest to embed a particular piece of logic within a component instead of linking to an external component.  For instance, in BizTalk, when would I write code in a map or orchestration versus call out to an external assembly?  That may seem obvious to a BizTalk guru, but not so much to a .NET guru who picks up BizTalk for the first time.  For Dynamics CRM, should I embed JavaScript on a form or reference an external JS file?
    5. What changes affect the object at an API level? This may relate to more UI-heavy platforms.  If I add validation or authorization requirements to a data entity on a screen, do those validation and security restrictions also come into play when accessing the object via the API?  Basically, I’m looking for which manipulations of an object are on a more superficial level versus all encompassing.
    6. How do you package up artifacts for source control or deployment? You can learn a lot about a platform by seeing how to package up a solution.  Is it a hodge podge of configuration files or a neat little installable package?  What are all the things that go into a deployment package?  This may give me an appreciation for how to build the solution on the platform.
    7. What is shared between components of the framework? I like to know what artifacts are leveraged across all pieces of the platform.  Are security roles visible everywhere?  What if I build a code contract or schema and want to use it in multiple subsystems?  Can I write a helper function and use that all over the place?
    8. What is supported vs. unsupported code/activities/tweaks? Most platforms that I’ve come across allow you to do all sorts of things that make your life harder later.  So I like to know which things break my support contract (e.g. screwing with underlying database indexes), are just flat out disallowed (e.g. Google App Engine and saving files to the VM disk), or just not a good idea.  In Dynamics CRM, this could include the types of javascript that you can include on the page.  There are things you CAN do, but things that won’t survive an upgrade.
    9. Where to go for help? I like to hack around as much as the next guy, but I don’t have time to bang my head against the wall for hours on end just to figure out a simple thing.  So one of the first things I look for is the support forums, best blogs, product whitepapers, etc.

    Did I miss anything, or are my priorities (ranking) off?

  • Interview Series: Four Questions With … Aaron Skonnard

    Welcome to the 20th interview in my series of discussions with “connected technology” thought leaders.  This month we have the distinct pleasure of harassing Aaron Skonnard who is a Microsoft MVP, blogger, co-founder of leading .NET training organization Pluralsight, MSDN magazine author and target of probably 12 other accolades that I’m not aware of.

    Q: What is the most popular training category within Pluralsight on Demand?  Would you expect your answer to be the same a year from now?  If not, what topics do you expect to increase in popularity?

    A: Currently our most popular courses are ASP.NET, MVC, and LINQ. These courses are rock-solid, nicely presented, and right up the alley of most Web developers today. A year from now I expect things to shift a little more towards today’s emerging topics like SharePoint 2010, Visual Studio 2010 (.NET 4), and Windows Azure. We’re building a bunch of courses in each of these areas right now, and now that they’re finally shipping, I’m expecting the training demand to continue to grow all year long. The nice thing about using our On-Demand library to ramp up on these is you get coverage of all topics for the price of a single subscription.

    Q: We’ve now seen all aspects of the Windows Azure platform get released for commercial use.  What’s missing from the first release of the Windows Azure AppFabric offering (e.g. application features, management, tooling)?  What do you think the highest priorities should be for the next releases?

    A: The biggest thing missing in V1 is tooling. The way things work today, it’s very difficult to manage a Windows Azure solution without building your own set of tools, which is harder to justify when the cloud is supposed to save you time/money. However, this presents an interesting opportunity for 3rd party tool vendors to fill the gap, and there are several already making a nice run for it today. One of my favorites is Cerebrata, the authors of Cloud Storage Studio and Azure Diagnostics Manager.

    The other thing I really wish they had made available in V1 was a “custom VM role”, similar to what’s offered by Amazon EC2. I believe they would get more adoption by including that model because it simplifies migration of existing apps by giving devs/admins complete control over the VM configuration via remote desktop. Since today’s roles don’t allow you to install your own software into the image, many solutions simply can’t move without major overhauls.

    For the next release, I hope they provide better tooling out of the box, better support for custom VM’s, and support for auto-scaling instances both up and down.

    Q: A number of years back, you were well known as an “XML guy.”  What’s your current thinking on XML as a transmission format, database storage medium and service configuration structure?  Has it been replaced in some respects as a format de-jour in favor of lighter, less verbose structures, or is XML still a critical part of a developer’s toolbox?

    A: : Back then, XML was a new opportunity. Today, it’s a fact. It’s the status-quo on most .NET applications, starting with the .NET configuration file itself. We’ve found more compact ways to represent information on the wire, like JSON in Ajax apps, but XML is still the default choice for most communication today. It’s definitely realized the vision of becoming the lingua franca of distribution applications through today’s SOAP and REST frameworks, and I don’t see that changing any time soon. And the world is a much better place now. 😉

    Q [stupid question]: You have a world-class set of trainers for .NET material.  However, I’d like to see what sort of non-technical training your staff might offer up.  I could see “Late night jogging and poetry with Aaron Skonnard” or “Whittling weapons out of soap by Matt Milner.”  What are some non-technical classes that you think your staff would be well qualified to deliver?

    A: Yes, we’re definitely an eccentric bunch. I used to despise running, but now I love it in my older age. My goal is to run one marathon a year for the rest of my life, but we’ll see how long it actually lasts, before it kills me. Keith Brown is our resident Yo-Yo Master. He’s already been running some Yo-Yo workshops internally, and David Starr is the up-and-comer. They both have some mad-skillz, which you can often find them flaunting at conferences. Fritz Onion is studying Classical Guitar and actually performed the 10sec intro clip that you’ll find at the beginning of our downloadable training videos. He’s so committed to his daily practice routine that he carries a travel guitar with him on all of his engagements despite the hassle. We also have a group of instructors who are learning to fly F-16’s and helicopters together through a weekly online simulation group, which I think they find therapeutic. And if that doesn’t impress you, we actually have one instructor who flies REAL helicopters for a special force that will remain unnamed, but that seems less impressive to our guys internally. In addition to this bunch, we have some avid musicians, photographers, competition sailors, auto enthusiasts (think race track), soccer refs, cyclists, roller-bladers, skiers & snowboarders, foodies … you name, we’ve got it. We could certainly author a wide range of On-Demand courses but I’m not sure our customers would pay for some of these titles. 😉

    Great stuf, Aaron.  Here’s to 20 more interviews in this series!

    Share

  • Leveraging Exchange 2007 Web Services to Find Open Conference Rooms

    Do you enjoy trying to find free conference rooms for meetings?  If you do, you’re probably a psycho who eats puppies.  I work at the headquarter campus of a large company with dozens upon dozens of buildings.  Apparently the sole function of my company is to hold meetings since it’s easier to find Hoffa’s body than a free conference room at 2 o’clock in the afternoon.  So what’s an architect with a free hour to do?  Build a solution!

    I did NOT build a solution to free up more conference rooms.  That involves firing lots of people.  Not my call.  But, I DID build a solution to browse all the conference rooms of a particular building (or buildings) and show me the results all at once.  MS Exchange 2007 has a pretty nice web service API located at https://%5Bserver%5D/ews/exchange.asmx.

    2010.4.23conf

    The service operation I was interested in was GetUserAvailability.  This guy takes in a list of users (or rooms if they are addressable) and a time window and tells if you the schedule for that user/room.

    2010.4.23conf2

    Note that I’m including the full solution package for download below, so I’ll only highlight a few code snippets here.  My user interface looks like this:

    2010.4.23conf3

    I take in a building number (or numbers), and have a calendar for picking which day you’re interested in.  I then have a time picker, and duration list.  Finally I have a ListVIew control to show the rooms that are free at the chosen time.  A quick quirk to note: so if I say show me rooms that are free from 10AM-11AM, someone isn’t technically free if they have a meeting that ends at 10 or starts at 11.  The endpoints of the other meeting overlap with the “free” time.  So, I had to add one second to the request time, and subtract one second from the end time to make this work right.  Why am I telling you this?  Because the shortest window that you can request via this API is 30 minutes.  So if you have meeting times of 30 minutes or less, my “second-subtraction” won’t work since the ACTUAL duration request is 28 minutes and 58 seconds.  This is why I hard code the duration window so that users can’t choose meetings that are less than an hour.  If you have a more clever way to solve this, feel free!

    Before I get into the code that makes the magic happen, I want to highlight how I stored the building-to-room mapping.  I found no easy way to query “show me all conference rooms for a particular building” via any service operation, so, I built an XML configuration file to do this.  Inside the configuration file, I store the building number, the conference room “friendly” name, and the Exchange email address of the room.

    2010.4.23conf4

    I’ll use LINQ in code to load this XML file up and pull out only the rooms that the user requested.  On to the code!

    I defined a “Rooms” class and a “RoomList” class which consists of a List of Rooms.  When you pass in a building number, the RoomList object yanks the rooms from the configuration file, and does LINQ query to filter the XML nodes and populate a list of rooms that match the building (or buildings) selected by the user.

    class Room
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Bldg { get; set; }
    
    }
    
    class RoomList : List<Room>
    {
        public void Load(string bldg)
        {
            XDocument doc = XDocument.Load(HttpContext.Current.Server.MapPath("RoomMapping.xml"));
    
            var query = from XElem in doc.Descendants("room")
                        where bldg.Contains(XElem.Element("bldg").Value)
                        select new Room
                        {
                            Name = XElem.Element("name").Value,
                            Bldg = XElem.Element("bldg").Value,
                            Email = XElem.Element("email").Value
                        };
            this.Clear();
            AddRange(query);
        }
    }
    

    With this in place, we can populate the “Find Rooms” button action.  The full code is below, and reasonably commented.

    protected void btnFindRooms_Click(object sender, EventArgs e)
        {
            //note: meetings must be 1 hour or more
    
            //load up rooms from configuration file
            RoomList rooms = new RoomList();
            rooms.Load(txtBldg.Text);
    
            //create string list to hold free room #s
            List<string> freeRooms = new List<string>();
    
            //create service proxy
            ExchangeSvcWeb.ExchangeServiceBinding service =
                new ExchangeSvcWeb.ExchangeServiceBinding();
    
            //define credentials and target URL
            ICredentials c = CredentialCache.DefaultNetworkCredentials;
            service.Credentials = c;
            service.Url = "https://[SERVER]/ews/exchange.asmx";
    
            //create request object
            ExchangeSvcWeb.GetUserAvailabilityRequestType request =
                new ExchangeSvcWeb.GetUserAvailabilityRequestType();
    
            //add mailboxes to search from building/room mapping file
            ExchangeSvcWeb.MailboxData[] mailboxes = new ExchangeSvcWeb.MailboxData[rooms.Count];
            for (int i = 0; i < rooms.Count; i++)
            {
                mailboxes[i] = new ExchangeSvcWeb.MailboxData();
                ExchangeSvcWeb.EmailAddress addr = new ExchangeSvcWeb.EmailAddress();
                addr.Address = rooms[i].Email;
                addr.Name = string.Empty;
    
                mailboxes[i].Email = addr;
            }
            //add mailboxes to request
            request.MailboxDataArray = mailboxes;
    
            //Set TimeZone stuff
            request.TimeZone = new ExchangeSvcWeb.SerializableTimeZone();
            request.TimeZone.Bias = 480;
            request.TimeZone.StandardTime = new ExchangeSvcWeb.SerializableTimeZoneTime();
            request.TimeZone.StandardTime.Bias = 0;
            request.TimeZone.StandardTime.DayOfWeek = ExchangeSvcWeb.DayOfWeekType.Sunday.ToString();
            request.TimeZone.StandardTime.DayOrder = 1;
            request.TimeZone.StandardTime.Month = 11;
            request.TimeZone.StandardTime.Time = "02:00:00";
            request.TimeZone.DaylightTime = new ExchangeSvcWeb.SerializableTimeZoneTime();
            request.TimeZone.DaylightTime.Bias = -60;
            request.TimeZone.DaylightTime.DayOfWeek = ExchangeSvcWeb.DayOfWeekType.Sunday.ToString();
            request.TimeZone.DaylightTime.DayOrder = 2;
            request.TimeZone.DaylightTime.Month = 3;
            request.TimeZone.DaylightTime.Time = "02:00:00";
    
            //build string to expected format: 4/21/2010 04:00:00 PM
            string startString = calStartDate.SelectedDate.ToString("MM/dd/yyyy");
            startString += " " + ddlHour.SelectedValue + ":" + ddlMinute.SelectedValue + ":00 " + ddlTimeOfDay.SelectedValue;
            DateTime startDate = DateTime.Parse(startString);
            DateTime endDate = startDate.AddHours(Convert.ToInt32(ddlDuration.SelectedValue));
    
            //identify the time to compare if the user is free/busy
            ExchangeSvcWeb.Duration duration = new ExchangeSvcWeb.Duration();
            //add second to look for truly "free" time
            duration.StartTime = startDate.AddSeconds(1);
            //subtract second
            duration.EndTime = endDate.AddSeconds(-1);
    
            // Identify the options for comparing free/busy
            ExchangeSvcWeb.FreeBusyViewOptionsType viewOptions =
                new ExchangeSvcWeb.FreeBusyViewOptionsType();
            viewOptions.TimeWindow = duration;
            viewOptions.RequestedView = ExchangeSvcWeb.FreeBusyViewType.Detailed;
            viewOptions.RequestedViewSpecified = true;
            request.FreeBusyViewOptions = viewOptions;
    
            //call service!
            ExchangeSvcWeb.GetUserAvailabilityResponseType response =
                service.GetUserAvailability(request);
    
            //loop through responses for EACH room
            for (int i = 0; i < response.FreeBusyResponseArray.Length; i++)
            {
                //if there is a result for the room
                if (response.FreeBusyResponseArray[i].FreeBusyView.CalendarEventArray != null && response.FreeBusyResponseArray[i].FreeBusyView.CalendarEventArray.Length > 0)
                {
                    //** conflicts exist
                }
                else  //room is free!
                {
                    freeRooms.Add("(" +rooms[i].Bldg + ") " + rooms[i].Name);
                }
    
            }
    
            //show list view
            lblResults.Visible = true;
    
            //bind to room list
            lvAvailableRooms.DataSource = freeRooms;
            lvAvailableRooms.DataBind();
    
        }
    

    Once all that’s in place, I can run the app, search one or multiple buildings (by separating with a space) and see all the rooms that are free at that particular time.

    2010.4.23conf5

    I figure that this will save me about 14 seconds per day, so I should pay back my effort to build it some time this year.  Hopefully!  I’m 109% positive that some of you could take this and clean it up (by moving my “room list load” feature to the load event of the page, for example), so have at it.  You can grab the full source code here.

    Share

  • How Do You Figure Out the Cost of Using the Azure AppFabric Service Bus?

    So the Windows Azure platform AppFabric was recently launched into production and made available for commercial use.  For many of us, this meant that Azure moved from “place to mess around with no real consequences” to “crap, I better figure out what this is going to cost me.” 

    I’ve heard a few horror stories of folks who left Azure apps online or forgot about their storage usage and got giant bills at the end of the month.  This just means we need to be more aware of our cloud service usage now.

    That said, I’ve personally been a tad hesitant to get back into playing with the Service Bus since I didn’t fully grok the pricing scheme and was worried that my MSDN Subscription only afforded me five incremental “connections” per month.

    Today I was pointed to the updated FAQ for AppFabric which significantly cleared up what “connections” really meant.  First off, a “connection” is established whether the service binds to the AppFabric Service Bus, and also when a client(s) bind to the cloud endpoint.  So if I have a development application and press F5 in Visual Studio, when my service and client bind to the cloud, that counts as 2 “connections.”

    Now if you’re like me, you might say “sweet fancy Moses, I’ll use up my 5 connections in about 75 seconds!”  HOWEVER, you aren’t billed for an aggregate count of connections, but a concurrent average.  From the FAQ (emphasis mine):

    That means you don’t need to pay for every Connection that you create; you’ll only pay for the maximum number of Connections that were in simultaneous use on any given day during the billing period. It also means that if you increase your usage, the increased usage is charged on a daily pro rata basis; you will not be charged for the entire month at that increased usage level.  For example, a given client application may open and close a single Connection many times during a day; this is especially likely if an HTTP binding is used. To the target system, this might appear to be separate, discrete Connections, however to the customer this is a single intermittent Connection. Charging based on simultaneous Connection usage ensures that a customer would not be billed multiple times for a single intermittent Connection.

    So that’s an important thing to know.  If I’m just testing over and over, and binding my service and client to the cloud, that’s only going to count as two of my connections and not put me over my limit.

    As for how this is calculated, the FAQ states:

    The maximum number of open Connections is used to calculate your daily charges. For the purposes of billing, a day is defined as the period from midnight to midnight, Coordinated Universal Time (UTC).Each day is divided into 5-minute intervals, and for each interval, the time-weighted average number of open Connections is calculated. The daily maximum of these 5-minute averages is then used to calculate your daily Connection charge.

    So, unless you are regularly binding multiple clients to an endpoint (which is possible when we’re talking about the event relay binding), you shouldn’t worry too much about exceeding your “connection pack” limits.  The key point is, connections are not incrementally counted, but rather, calculated as part of concurrent usage.

    Hope that helps.  I’ll sleep better tonight, and bind to the cloud better tomorrow.

    Share

  • Debatching Inbound Messages from BizTalk WCF SQL Adapter

    A few years back now (sheesh, that long already??) I wrote a post about debatching messages from the classic BizTalk SQL adapter.  Since that time, we’ve seen the release of the new and improved WCF-based SQL adapter.  You can read about the new adapter in a sample chapter of my book posted on the Packt Publishing website.  A blog reader recently asked me if I had ever demonstrated debatching via this new adapter, and to my surprise, I didn’t found anyone else documenting how to do this.  So, I guess I will.

    First off, I created a database table to hold “Donation” records.  It holds donations given to a company, and I want those donations sent to downstream systems.  Because I may get more than one donation during a WCF-SQL adapter polling interval, I need to split the collection of retrieved records into individual records.

    After creating a new BizTalk 2009 project, I chose to Add New Item to my project.  To trigger the WCF-SQL adapter wizard, you choose Consume Adapter Service here.

    2010.4.8sql01

    After choosing the sqlBinding as the adapter of choice, I chose to configure my URI.  After setting a polling ID, server name and database name on the URI Properties tab, I switched to the Binding Properties tab and set the adapter to use Typed Polling.

    2010.4.8sql02

    Next, I set my PollingDataAvailableStatement to a statement that counts how many records match my polling query.  Then I set the PollingStatement value to look for any records in my Donation table where the IsProcessed flag is false.

    2010.4.8sql03

    With my URI configured, I connected to the database, switched to the Service contract type (vs. Client), I’m able to choose the TypedPolling operation for my database.

    2010.4.8sql04

    When I complete the wizard, I end up with one new schema (and one binding file) added to my project.  This project has a few root nodes which make up the tree of records from the database.

    2010.4.8sql05

    To make sure things work at this moment, I built and deployed this application.  I added the wizard-generated binding file to my BizTalk application so that I’d get an automatically configured receive location that matches the WCF-SQL adapter settings from the wizard.

    2010.4.8sql06

    After creating a send port that grabs all records from this new receive location, I started the application.  I put a new row into my database, and sure enough, I got one file emitted to disk.

    2010.4.8sql08

    That was easy.  If I create TWO records in my database, then I still get a single message/file out of BizTalk.

    2010.4.8sql09

    So, we want to split this up so that these two records show up as two distinct messages/files.  When using the old adapter, we had to do some magic by creating new schemas and importing references to the auto-generated ones.  Fortunately for us, it’s even easier to debatch using the WCF-SQL adapter.

    The reason that you had to create a new schema when leveraging the old adapter is that when you debatched the message, there was no schema matching the resulting record(s).  With the WCF-SQL adapter, you’ll see that we actually have three root nodes as part of the generated schema.  We can confirm this by looking at the Schemas section in the BizTalk Administration Console.

    2010.4.8sql10

    So, this means that we SHOULD be able to change the existing schema to support debatching, and HOPEFULLY it all just works.  Let’s try that.  I went back to my auto-generated schema, clicked the topmost Schema node, and changed its Envelope property to Yes.

    2010.4.8sql12

    Next, I clicked the TypedPolling node (which acts as the primary root that comes out of the adapter) and set the Body XPath value to the node ABOVE the eventual leaf node.

    2010.4.8sql13

    Finally, I selected the leaf node and set its Max Occurrence from Unbounded to 1.  I rebuilt my project and then redeployed it to the BizTalk Server.  Amazingly enough, when I added two records to my database, I ended up with two records out on disk.

    2010.4.8sql11

    Pretty simple, eh?  When the record gets debatched automatically by BizTalk in the XML receive pipeline, the resulting TypedPollingResultSet0 message(which matches a message type known by BizTalk) gets put in the MessageBox and routed around.

    Has anyone done this yet?  Any experiences to share?  This used the TypedPolling mechanism, but hopefully it’s not too different with other polling mechanisms.

    Share