The Oracle Adapter in BizTalk Adapter Pack v2.0

February 12, 2010 4 comments

Has anyone been successful creating schemas based off of an Oracle package using the new Oracle adapter (BAP v2.o)?  We had a Business Adapter Pack v1.0 send port that utilized an Oracle package.  When we upgraded to v2.0, it stopped working showing an error like this:

Event Type: Warning
Event Source: BizTalk Server 2006
Event Category: (1)
Event ID: 5743
Date:  2/12/2010
Time:  11:57:06 AM
User:  N/A
Computer: YOUR_SERVER
Description:
The adapter failed to transmit message going to send port “ProcessGSTUpsert.WCF” with URL “oracledb://oracle_server_name/”. It will be retransmitted after the retry interval specified for this Send Port. Details:”Microsoft.ServiceModel.Channels.Common.TargetSystemException: ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to ‘UPDATE_PROCEDURE’
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored —> Oracle.DataAccess.Client.OracleException ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to ‘UPDATE_PROCEDURE’
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
at Microsoft.Adapters.OracleCommon.OracleCommonUtils.ExecuteNonQuery(OracleCommand command, OracleCommonExecutionHelper executionHelper)
— End of inner exception stack trace —
<Server stack trace:
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndRequest(IAsyncResult result)Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.Channels.IRequestChannel.EndRequest(IAsyncResult result)
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.RequestCallback(IAsyncResult result)”.

I tried recreating the schema used by the Oracle adapter, but it complains as follows:

The categories in the ‘Added categories and operations’ list contain no operations for metadata generation.

This worked before the upgrade.  Any ideas?

15-Feb-2010 Update:

See my reply to Antti – the runtime aspect of the problem was figured out.  I’ll see if I can find a solution to the schema-generation problem.

Advertisements
Categories: BizTalk Server

BizTalk Server 2006 R2 SP1 – Have you tried it?

February 5, 2010 21 comments

As you may know, SP1 for BizTalk 2006 R2 was released about a week ago.  Reading the BizTalk Server Team blog, it sounds quite impressive – like an update I would surely want on my servers.  However, in troubleshooting with Microsoft a problem I have with performance on one of our servers, the gentleman I worked with recommended I not install it – at least not yet.  That puzzled me a bit.  He indicated that he had one customer who installed it, and after having a problem, was having trouble reversing (uninstalling) the service pack.

So I thought it’d be interesting to get your opinion on SP1.  Have you installed it?  Did you have any trouble?  Did you notice any of the benefits described by the product team?  Let me know how well your experience went.

[Update as of 8-Feb-2010]:

One of the Microsoft Escalation Engineers read my post and wanted me to feel certain that there aren’t any issues with the installation of SP1 for BizTalk 2006 R2.  Apparently the only “issue”, if you can call it that, is that the DB schema changes with SP1, so if a rollback was required, it is more complicated because the database needs to be restored to a time point pre-Sp1.  I guess I should add that the uninstallation is not supported by Microsoft either.  I’d certainly read through the SP1 Installation Guide though before starting the upgrade process.  There’s a lot to check before installing.

Because SP1 sounds like it has a lot of improvements I’m going to have SP1 installed on our servers soon – I’ll post an update once that happens (it will take a few weeks to get this into production).

Categories: BizTalk Server

BizTalk Disaster Recovery Planning

January 5, 2010 18 comments

I agree with Nick Heppleston’s post entirely in that you had better test your DR plan in advance of the real disaster if you really want it to work!  I can speak from experience here – my company’s previous plan sounded perfectly fine to me when I worked on it.  In fact, when I discussed the plan with Tim Wieman and Ewan Fairweather they also agreed that it sounded reasonable (to their credit they didn’t get to see a written plan and they both cautioned that I had better test things to be sure).  But, as you can probably already guess, when tested, the plan didn’t work.  In this post I’ll talk about what I did (that didn’t work) so that you can avoid doing the same thing, and then point out a shortcoming in the MSDN documentation, as I see it.

Here’s what I attempted to do.  Since our test/QA environment resides in another data center, far away from our production environment, we decided to use the test environment as our DR environment in the case of a lasting failure in the normal production site.  In a few words, we were planning for a scenario where we’d lose both the BizTalk application servers and the  SQL Server databases.  We thought this was reasonable since many disasters could easily prevent both sets of hardware to stop functioning for an extended period of time.

Here’s a high-level overview of the steps we had in place before the disaster:

  1. We had configured regular backups with transaction log shipping on the destination (DR) database server.
  2. We had the IIS web directories and GAC of the BizTalk application servers backed up to the DR BizTalk application servers.
  3. We had a backup of the master secret available on the DR BizTalk application servers.

Here’s a high-level overview of the steps we had after the disaster:

  1. Recover the production binaries and production web directories onto the test servers.
  2. Restore the production database using the DR instance.
  3. Unconfigure the test BizTalk application servers.
  4. Run the UpdateDatabase.vbs script and UpdateRegistry.vbs script on the test BizTalk application servers.
  5. Reconfigure the test BizTalk application servers, joining the SSO and BizTalk Groups.
  6. Recover Enterprise Single Sign-On.

In early November, we tested the scenario.  To make a long story short, it didn’t work.  Microsoft, also uncertain why things didn’t work (at first anyway), suggested a “hack” to get things working.  That hack would then be reviewed by the product team, which would hopefully provide their final blessing.  The hack involved editing the SSOX_GlobalInfo table (part of the SSODB), updating gi_SecretServer with the “new” test server that would become the master secret server.  It appeared that it worked at first, but a deeper look into things showed that we were wrong (it only appeared to be working because the real production master secret server had been brought up by that point – since the DR exercise was taking too long – so that both BizTalk groups were running at the same time).

The problem that we faced can be summarized as follows: the MSDN documentation makes an assumption, which wasn’t true in our case.  Specifically, Microsoft expects the new master secret server (the test BizTalk app server in our case), to have the same name as the previous master secret server OR for the new master secret server to already be a part of the group prior to the disaster (of course it wouldn’t have been the master secret server prior to the disaster).  These limitations don’t really have anything to do with BizTalk, but rather with the Enterprise Single Sign-On product.  I think they are unrealistic expectations, but limitations nonetheless.

In conclusion, you had better test out your DR scenario if you haven’t already, or be prepared for some ugly surprises.  Please share your experiences with me.  What does your DR plan assume?  Have you had a nasty experience?

Categories: BizTalk Server

BizTalk Map Bug Causes Inconsistent Results

November 11, 2009 1 comment

I found what I would call a bug with the BizTalk Mapper (does anyone dare call it a feature?).  Let me show a simple version of the problem I encountered:

I created a BizTalk project that contains a map that calls an external assembly (in my case part of the same solution), such as:

BizTalk Solution contains a Reference

My external assembly is version 1.0.0.0, compiled in Development mode, and it looks like this:

public class Helper
{

public string ReturnVersion(string ignore)
{
return “1.0.0.0”;
}

}

I deployed the map and the assembly.  I tested the map.  Sure enough, “1.0.0.0” is mapped to “SomethingElse”.  No surprises yet.

I then changed the ReturnVersion function to return “1.0.0.1”.  Similarly, I incremented the version of the external assembly and BizTalk project and compiled in Release mode (let’s pretend I’m done with development and I’m now ready to release).  I double checked the references in the Solution Explorer – sure enough Blog.ShowMapBug.Utilities shows the new version as the reference.

Properties Window

I deployed the solution and GAC’d the assembly.  I updated my send port to use the new map.  I restarted the Host Instance.  I then tested things out.  What would you expect to get mapped to SomethingElse?  1.0.0.1, right?  Well it doesn’t work.  1.0.0.0 still shows up.  Why?

If I open the BizTalk map in an XML editor and search for the assembly, I find:

<Script Language=”ExternalAssembly” Assembly=”Blog.ShowMapBug.Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e767c75a9f3ac928″ Function=”ReturnVersion” AssemblyPath=”..\Blog.ShowMapBug.Utilities\obj\Debug\Blog.ShowMapBug.Utilities.dll” />

So, you’re now thinking what I thought.  Okay, just update the Version number there, right?  Nope.  It turns out that the version number here gets ignored altogether and “1.0.0.0” will continue to get mapped to “SomethingElse” (using the old assembly).

So what’s going on?  It turns out that the problem is the AssemblyPath reference.  It’s pointing at the “Debug” version of the external assembly.  Once deployed, you’d THINK this wouldn’t be a problem, but it is.  The only way to fix this problem is to point the DLL at the Release mode version of the file, i.e. AssemblyPath=”..\Blog.ShowMapBug.Utilities\obj\Release\Blog.ShowMapBug.Utilities.dll.

Amazing, isn’t it?  Of course in this simple scenario it wasn’t too hard to follow.  But of course real maps, real external assemblies and real projects are much more complex, and it took me a few hours to figure out why in the world the project wasn’t behaving as it was expected to.

 

Categories: BizTalk Server

Switch from WCF-BasicHttp to WCF-WSHttp in BizTalk?

October 30, 2009 8 comments

I learned a new trick that I know someone out there will appreciate…

First, here’s a little background. Some time ago, when I hosted my first BizTalk service with WCF, I ran the BizTalk WCF Service Publishing Wizard and was prompted for an adapter name.  I chose WCF-BasicHttp, assuming that I could easily change this later (as most of you out there, it’s nice to start with no security, get things working, and then progress to enable more complicated security schemes).
BizTalk WCF Publishing Wizard

And for those that I haven’t done this before: After finishing the wizard, the next steps involve verifying/fixed the IIS app pool settings and enabling the receive location.  After that, you should be able to browse the service.  Something like this should appear:

Browse WCF Service

If you click on the link to browse the WSDL, you’d find that there is no advanced policy configuration.

Great, we’ve got our basic http service up.  At some point, you might want something a little more secure, and this was my initial frustration.  I opened up the BizTalk Admin Console, found the receive location hosting the service, and switched from WCF-BasicHttp to WCF-WSHttp.  As part of this, in my case, I added the URI, specified a Security mode of Transport, and a Transport client credential type of Basic.

WCF-WSHttp Receive Location

I accepted the changes, made sure the receive location was enabled, and tried browsing my service again.

Error Browsing the WSHttp Service

But, as you can see, it didn’t work.  At the time, not knowing how to fix this, I re-ran the wizard, chose WSHttp, etc.  That made the WSHttp service browsable, but I was frustrated that I had to re-run the wizard, and I happened to have chosen a slightly different naming for the operation, which caused additional headache and rework, etc.

That’s why I’m writing this post.  There’s a better way.  Let’s go back in time… instead of re-running the wizard and choosing the WSHttp adapter (or Custom-Isolated), I could have simply changed the .svc file, i.e. C:\Inetpub\wwwroot\HelloWorldService\HelloWorld.svc.  The file originally had this inside it:

<%@ ServiceHost Language=”c#” Factory=”Microsoft.BizTalk.Adapter.Wcf.Runtime.BasicHttpWebServiceHostFactory, Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ %>

I changed the HelloWorld.svc ever so slightly to read:

<%@ ServiceHost Language=”c#” Factory=”Microsoft.BizTalk.Adapter.Wcf.Runtime.WSHttpWebServiceHostFactory, Microsoft.BizTalk.Adapter.Wcf.Runtime, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ %>

I saved the file, and… (drum roll please)

WSHttp WSDL

It works!  Here I’m showing the WSHttp WSDL.  You’ll notice that you see the corresponding policy information in the file.

So, in conclusion, yes you can start with one WCF adapter type and switch it later by 1) updating the receive location in the Admin Console, and 2) updating the .svc file.  For reference here are factory values for the .svc file that the wizard allows you to pick from:

BasicHttp: Microsoft.BizTalk.Adapter.Wcf.Runtime.BasicHttpWebServiceHostFactory

WSHttp: Microsoft.BizTalk.Adapter.Wcf.Runtime.WSHttpWebServiceHostFactory

Custom-Isolated: Microsoft.BizTalk.Adapter.Wcf.Runtime.CustomWebServiceHostFactory

Good luck!

Categories: BizTalk Server

BizTalk R2 Authorization using WCF

October 6, 2009 4 comments

As some of you may have noticed, I gave a rather scathing review of how WCF implements authorization (and hence how R2 implements authorization for WCF services).  To see that post, click here.  Although I’m still very disappointed, I’d like to share an approach that accomplishes the goal I had in mind: being able to dynamically specify, via means of configuration, the users that should have access rights to the service.  This approach was built by Vijay Naidu, a colleague of mine.

Vijay read my first blog, and took the time to “code” authorization into his web service.  With a little tuning, the solution you’re about to see resulted, which I think is much better than the out-of-the-box solution.  This solution leverages the SSO database to store the authorized users (the code example you’ll see in this post is written to authorize a single user, but hopefully you wouldn’t have trouble using a delimited list of users).  In addition, Vijay’s solution creates a shared component that can be leveraged by multiple projects without recoding the initial setup.  When mixed with Richard Seroter’s SSO storage tool (I use the variant by Paul Petrov), you’ll find that you can set up authorization dynamically.  Hence, I figured you might be interested.  Here were the steps involved:

First, the machine.config file was modified adding this entry:

<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name=”AcmeWCFCustomAuth” type=”Acme.WcfServiceBehaviors.CustomBehaviorElement, Acme.WcfServiceBehaviors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=02ae73d8d306f338″ />
</behaviorExtensions>
</extensions>
</system.serviceModel>

Secondly, this code was written and added to an assembly (the one mentioned above in the machine.config file).

if (context.PrimaryIdentity.IsAuthenticated)
{
userName = context.PrimaryIdentity.Name;
//Get the application name for parsing the Endpoint Uri Absolutepath (ex: /Acme.GlobalSafety.EnsureSafety/ImportantAuth.svc)
ApplicationName = operationContext.EndpointDispatcher.EndpointAddress.Uri.AbsolutePath.ToString();
WcfUriAbsolutePath = ApplicationName.Split(‘/’);
ApplicationName = WcfUriAbsolutePath[1].ToString();(ex: Acme.GlobalSafety.EnsureSafety)
//Get the SSO Config entry for the user to authenticate (ex: domain\LoginUser).  This call refers to the SSO tool mentioned earlier
wcfAuthUserName = Acme.SSO.Utility.SSOConfigHelper.Read(ApplicationName, “WCFClientAuthUserName”);
if (string.Compare(userName.ToUpper(), wcfAuthUserName.ToUpper()) != 0)
return false; //this returns an access denied error
}

This assembly was then compiled, installed in the GAC, and the BizTalk host was restarted. Next, using the BizTalk Administrator, a Request/Response WCF-Custom receive location was created.  Under the Service Behavior tab the AcmeWCFCustomAuth binding was added.

Next, the WCFClientAuthUserName property was added to the SSO Config database (using the tool mentioned earlier).

That’s it.  It may have seem like a bunch of work (and I admit that I don’t want developers redoing this entire thing), which is the beauty of this solution.  Subsequent applications that want to leverage this solution only need to repeat the steps in the last two paragraphs, which isn’t bad.  The other advantage of this approach, as opposed to putting the username in some configuration file out on disk, is that the SSO databases are part of the BizTalk daily backup job.  In the event of a disaster, they will be recovered, along with all of your beautiful authorization configurations.  🙂

Categories: BizTalk Server

BizTalk R2 WCF Authorization

June 18, 2009 1 comment

Let me share a quick story.  We’ve been using BizTalk Server 2006 for a couple of years now at my company.  We recently upgraded to R2, and I was excited to get the opportunity to work with WCF… so a few months ago I created my first WCF service.  Things worked about like what I expected except for one thing: authorization.  I kept thinking, “this has got to be really easy” yet I could never figure out how to restrict access to certain users (this was fairly easy to do with ASMX services).  That’s what’s leading me to write this post.

There are a few things I like a lot more about WCF, but there’s one thing I can’t stand: the way authorization is implemented.  Here’s why:

From what I’ve seen and heard, WCF is intended to make security easier by allowing this to be configured in XML configuration files.  This is neat because the developer can do his/her work easily, and the details on security can be configured dynamically (without recompiling).   It’s indeed pretty cool that you can change from using Windows Authentication to basic auth, etc. all in a configuration file.  However, this “guiding principle” behind WCF doesn’t hold true when it comes to authorization!  I couldn’t believe my eyes when I read this post:

http://social.msdn.microsoft.com/Forums/en-US/biztalkr2adapters/thread/12a47533-acb4-4ff4-bc32-d8ea305cb066

Are you serious?  I have to write a WHOLE BUNCH of code just to restrict access to a web service?!  There’s not a wizard for this?  Or perhaps some GUI control?  No XML file for this?  Or how about clicking on “Permissions” in IIS like you used to be able to do with ASMX services?  So much for configuring security in an XML file.  I’m deeply disappointed.

In fact, I really hope I’m wrong.  Perhaps there’s some easier way that I just happened to have missed.  Please do tell me this is the case and end this bad dream.

Since I refuse to manage web service access via code for what might end up to become hundreds (or even thousands) of web services, I’ll have to do this some other way.  I think I’ll use SOA’s Service Manager to control authorization (I should get paid for promoting them).  There it can be done easily at the operation level of a web service.  I just thought WCF would have done something like this too.

Categories: BizTalk Server