Configured adaptor

Topics: Developer Forum, User Forum
Mar 26, 2009 at 6:43 PM
Hi,

I'm having trouble figuring out how to configure an adapter that is outside the ESB\LOBSystems folder.
The reason I don't want to use convention over configuration is that I have existing services that I want to plug in and want to retain my existing directory structure.
There will be thousands of services and I want to create a VS 2k8 C# template that can easily be added to wrap these services to expose them to ESB.NET.

Anyway, I've added a PipelineConfig/Vertical/PipelineMapSection node to \ESB.NET\6.2.9.0_x64\Source\ESB\Base\Solutions\Main\Configuration\XMLConfigFiles\ServicePipeline.config, but am currently getting an error when attempting to run a sample XML through:

System.Exception: Attempted to create object:com.MyDomain.rateRTMarket.rateRTMarketHandler1.0.0.0 in Assembly:

D:\Visual Studio\ESB.NET\6.2.9.0_x64\Source\ESB\LobSystems\ns\com.MyDomain.MyService.MyServiceHandler1.0.0\bin\com.MyDomain.MyService.MyServiceHandler1.0.0.dll Failed.
   at ESB.Adaptors.Application.Services.ConventionOverConfig.InvokeViaConvention.InvokeObject(String& sTransactionComponent, String& sComponentServer, Envelope& oEnvRq, Envelope& oEnvRs)
   at ESB.Adaptors.Application.Services.ConventionOverConfig.InvokeViaConvention.DoWork()
   at ESB.Adaptors.Application.Services.ConventionOverConfig.InvokeViaConvention.ProcessMsgSync(IEnvelope oEnv)
   at ESB.Core.Pipeline.PipelineExecuter.InvokeObjectCLR(IProcessMsg& oESBIf, Envelope& oEnvRq)"
Source="ESB.Adaptors.Application.Services.ConventionOverConfig"

Why is it still trying to use convention over config?

Here is my pipeline entry:
                    <PipelineMapSection>
                        <PipelineEntry>
                            <ResolveNameEntry>
                                <ContextEntry>
                                    <Context>com.MyDomain.MyService.MyServiceHandler1.0.0.0</Context>
                                    <ResolveName>MyServiceRequestType::http://schemas.datacontract.org/2004/07/MyServiceESBNETAdaptor</ResolveName>
                                    <PipelineID>1</PipelineID>
                                    <ProcessInParallel>0</ProcessInParallel>
                                    <ResponseIsRequestForNextPipelineItem>0</ResponseIsRequestForNextPipelineItem>
                                    <MultiLevelOverrides>
                                        <!-- RequestQ is the MSMQ queue for the request. -->
                                        <RequestQ/>
                                        <!-- TransactionComponent is .NET CLR class name. -->
                                        <TransactionComponent>MyServiceESBNETAdaptor.MyServiceHandler</TransactionComponent>
                                        <!-- Full assembly path -->
                                        <ComponentServer suffix="no">D:\Projects\Services\MyService\MyServiceESBNETAdaptor\bin\MyServiceESBNETAdaptor.dll</ComponentServer>
                                        <!-- Object broker is ??? -->
                                        <UseObjectBroker>0</UseObjectBroker>
                                        <ObjectBroker/>
                                        <ObjectBrokerServer/>
                                        <!-- Schema validation settings.-->
                                        <ValidateInputSchema>0</ValidateInputSchema>
                                        <ValidateOutputSchema>0</ValidateOutputSchema>
                                        <IgnoreInputSchemaValidationErrors/>
                                        <IgnoreOutputSchemaValidationErrors/>
                                        <!-- Other ContextEntry properties
                                        <Enabled/>
                                        <AlwaysExecute/>
                                        <ExecuteIfNoMatchFound/>
                                        <PMAsyncConfirmation/>
                                        <XSLName/>
                                        <InputSchema/>
                                        <OutputSchema/>
                                        -->
                                        <!-- Custom parameters to the assembly. -->
                                        <Custom>
                                            <ParamName/>
                                            <ParamValue/>
                                        </Custom>
                                    </MultiLevelOverrides>
                                </ContextEntry>
                            </ResolveNameEntry>
                        </PipelineEntry>



Coordinator
Mar 27, 2009 at 11:41 AM

 

Hi

 

1) Insight to your problem

I suspect the reason for this error is that the request message is not correctly formed. The configuration looks good.

i.e. It does not have the correct ResolveName and Context in the request, must match that of the Configuration.

 

   <Context>com.MyDomain.MyService.MyServiceHandler1.0.0.0</Context>

   <ResolveName>MyServiceRequestType::http://schemas.datacontract.org/2004/07/MyServiceESBNETAdaptor</ResolveName>

 

I suspect this is because you did not setup the BSDL with a Request Schema Root Element Name and Namespace.

As a result, when you click "Sample Request" (which creates the sample using the BSDL), it will not create a request message that invokes your service.

 

2)What to do to fix it

Option 1 [recommended] - Populate the BSDL supplying a valid schema name and namespace to match your request.

To do this:

i)From the service pipeline configuration page, select the "View BSDL" for the service.

ii)Near the top of the page, there's a Service Definition File Path  tag with the path to the service definition next to it.

...something like:

C:\ESBDeploy\6\6.2.9.0_x64\Source\ESB\Base\Solutions\Main\Management\ESB.Management.Portal\ServiceDefinitions\ServiceDefinition.WindowsWorkflow3.0.StartCase2.ProcessWFTxn1.0.0.0.xml

 

Open up that file with a text editor, and change the bits in Red.

 

<?xml version="1.0" encoding="utf-8"?>

<Services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:au.com.keystroke.serviceDefinition.version_1_0_0_0">

  <ServiceDefinition>

    <Service>

      <DistinguishedServiceName>

        <ServiceName>WindowsWorkflow3.0.StartCase2.ProcessWFTxn1.0.0.0</ServiceName>

      </DistinguishedServiceName>

      <Request>

        <Document>

          <Schema>

            <Name>MyServiceRequestType</Name>

            <Namespace>http://schemas.datacontract.org/2004/07/MyServiceESBNETAdaptor</Namespace>

          </Schema>

        </Document>

      </Request>

      <Response />

      <ServiceProviderName>Keystroke IT Australia</ServiceProviderName>

    </Service>

    <Characteristics />

    <Documentation />

    <BusinessAttributes />

    <ServiceImplementaion />

  </ServiceDefinition>

</Services>

 

iii)Save the file & then generate the sample request again.

 

Option 2[if it all gets too hard] - Create a message manually and paste it into the Generic Request Sender page.

 

3)Useful background info

3.1) The Service Pipeline Manager runs & looks for matches, caches in hashtable etc.

The ConventionOverConfiguration functionality is simple a handler that runs at the end of the Service Pipeline (configured in the Pipeline) and look for scenarios where there was no Configured match in the Pipeline for a given request.

Once it detects this, it runs it's rules - Based upon a Convention, to detect whether the request can be handled using the Convention built into the ConventionOverConfiguration handler.

 

In this case, because the request sent did not match any configuration, the ConventionOverConfiguration handler decided to try & see if there was anything that would match it's convention that could satisfy this request.

 

4)Other recommendations

4.1)If you plan to not use the ConventionOverConfiguration feature for a particular instance, you should probably disable it to improve performance, as it will otherwise kick in needlessly.

If you plan to still use it in conjunction with the configured services, then leave it in.

 

4.2)It's great to hear that you're planning to build lots of services with ESB.NET.

Note that you can write/customize the ConventionOverConfiguration handler to meet your own requirements.

If you have an existing structure that has a rigid convention, then maybe this can be a way to minimize the amount of work you need to do to route the services through ESB.NET.

 

4.3)With that many services, I suggest you plan your federation strategy. For many reasons, you'd want to group your services into logical namespaces & probably related ESB.NET instances. This will greatly help with maintenance & overall availability/uptime.

Instances that map to namespaces are a great way to get up & running quickly. Override by re-routing requests [configure in a routing config for that service or request re-mapping if needed on a large scale etc.] on an as-need basis.

 

You can also modify the RequestHandlerProxy to have any routing logic conventions/configuration built into it to make life on the server side easier/cleaner if you need to [just keep this option in your back pocket in case you need it].

 

4.4)With the services you've got built, you can also look at having an interpreter handler run before/after each of your service to do any generic translation that needs to be done for each service you're invoking.

 

If you need any more guidance, email me on minas@optusnet.com.au.

 

HTH

Good luck

 

Cheers

Minas

Mar 27, 2009 at 6:22 PM
Ok, I've gotten a little further.
My problem was a bit of a misunderstanding on how best to do things. In my first attempt, I read through all the documentation I could find and tried to create files manually based on what I read.
There's a much easier way as Minas has eluded to above.

To hook up an existing service to ESB.NET, my advice to you is to start in ServicePipeline.config.
You will find this file at \ESB.NET\6.2.9.0_x64\Source\ESB\Base\Solutions\Main\Configuration\XMLConfigFiles\ServicePipeline.config.

Create a "ESB.Core.Pipeline/Config/PipelineConfig/Vertical/PipelineMapSection" node for your service (see example below).
Save the ServicePipeline.config changes and browse to "Service Pipeline" in ESB Management console.
Click View BSDL on your service.  This will create the BSDL file shown at the top to the resulting page.
  \ESB.NET\6.2.9.0_x64\Source\ESB\Base\Solutions\Main\Management\ESB.Management.Portal\ServiceDefinitions\ServiceDefinition.com.fsc.MyServiceESBNETAdaptor.1.0.0.0.xml
Modify this file in a text editor, adding a "ServiceDefinition/Service/Request/Document/Schema/Url" node that points to your service handler's schema.
Save your changes, return to "Service Pipeline" in ESB Management console and try the "Sample Request" link on your service.
You should see an xml example that you can adjust and "Send Request".  (This is still failing for me with an unhandled exception somewhere, but I believe the steps so far are proper.  Minas, please verify and/or comment.  Note: I have added the MyServiceHandler class to my service - extends ESB.Adaptors.Application.Workflow.ServiceBase -, but I am getting a Server Application Unavailable message and nothing in the Event log.)

Server Application Unavailable

The web application you are attempting to access on this web server is currently unavailable.  Please hit the "Refresh" button in your web browser to retry your request.

Administrator Note: An error message detailing the cause of this specific request failure can be found in the application event log of the web server. Please review this log entry to discover what caused this error to occur.




PipelineMapSection example:
                    <PipelineMapSection>
                        <PipelineEntry>
                            <ResolveNameEntry>
                                <ContextEntry>
                                    <Context>com.myDomain.MyServiceESBNETAdaptor.1.0.0.0</Context>
                                    <ResolveName>MyServiceRequestType::http://schemas.datacontract.org/2004/07/MyServiceESBNETAdaptor</ResolveName>
                                    <PipelineID>1</PipelineID>
                                    <ProcessInParallel>0</ProcessInParallel>
                                    <ResponseIsRequestForNextPipelineItem>0</ResponseIsRequestForNextPipelineItem>
                                    <MultiLevelOverrides>
                                        <!-- RequestQ is the MSMQ queue for the request. -->
                                        <RequestQ/>
                                        <!-- TransactionComponent is .NET CLR class name. -->
                                        <TransactionComponent>MyServiceESBNETAdaptor.MyServiceHandler</TransactionComponent>
                                        <!-- Full assembly path -->
                                        <ComponentServer suffix="yes">\MyService\MyServiceESBNETAdaptor\bin\MyServiceESBNETAdaptor.dll</ComponentServer>
                                        <!-- Object broker is ??? -->
                                        <UseObjectBroker>0</UseObjectBroker>
                                        <ObjectBroker/>
                                        <ObjectBrokerServer/>
                                        <!-- Schema validation settings.-->
                                        <ValidateInputSchema>0</ValidateInputSchema>
                                        <ValidateOutputSchema>0</ValidateOutputSchema>
                                        <IgnoreInputSchemaValidationErrors/>
                                        <IgnoreOutputSchemaValidationErrors/>
                                        <!-- Other ContextEntry properties
                                        <Enabled/>
                                        <AlwaysExecute/>
                                        <ExecuteIfNoMatchFound/>
                                        <PMAsyncConfirmation/>
                                        <XSLName/>
                                        <InputSchema/>
                                        <OutputSchema/>
                                        -->
                                        <!-- Custom parameters to the assembly. -->
                                        <Custom>
                                            <ParamName/>
                                            <ParamValue/>
                                        </Custom>
                                    </MultiLevelOverrides>
                                </ContextEntry>
                            </ResolveNameEntry>
                        </PipelineEntry>
                        <MultiLevelOverrides>
                            <RequestQ/>
                            <ComponentServer suffix="yes">C:\Projects\Services</ComponentServer>
                            <TransactionComponent> </TransactionComponent>
                            <Custom>
                                <ParamName> </ParamName>
                                <ParamValue> </ParamValue>
                            </Custom>
                        </MultiLevelOverrides>
                    </PipelineMapSection>


Mar 27, 2009 at 8:29 PM
I got past the Server Application Unavailable error.
It turns out the event log was full and it stopped ESB.NET from completely processing the request.

The event it was trying to log was:
Could not invoke start async logger URL : http://localhost/ESB/Source/AsyncLogger/MsmqToMsSql.aspx. Service URL invoking is:http://localhost/ESB/Source/CoreInternetTransportAdaptors/Wcf/ESBSoapXmlDocTransport.svc/Default

I thought I had SQL logging turned off, but maybe it isn't.


Anyway, I have confirmed that my configured adapter is firing.

Thanks for your help, Minas.  (BTW: I'm still interested in your comments of the email I sent you.)