none
How to finish a custom pipeline component to force a send port retry RRS feed

  • Question

  • Hi,

    is there a way to end a custome pipeline component i a way to force a retry acording to the send port transport configuration?

    My pipeline component retrieves a target endpoint address (for the send adapters target) from an external web service. Sometimes the external system needs some minutes to process its task before my endpoint address will be available. So, my pipeline component tries to get the address and should force a sendport retry if the external service is not ready.

    If I throw an exception in my first pipeline component, the second component will not be entered, but the message is going to suspend.

    If I return null, no message will be alive to take a retry.

    I expected dehydrated massages with an increasing retry counter, until the configured retries limit is reached.

    btw: I'm in a messaging only scenario. No orchestrations so far.

    Is this possible, or am I on a wrong track with this approach?

    Thanks for any hint!


    • Edited by Heiko Wrede Wednesday, October 5, 2016 11:16 AM
    Wednesday, October 5, 2016 10:27 AM

Answers

  • Hi ,

    You should use Orchestration here ..nothing wrong with it:)

    Just give a call to the service which will return the endpoint address and then create a dynamic send port to send the message top.

    Regards,


    Mandar Dharmadhikari

    • Marked as answer by Heiko Wrede Friday, October 7, 2016 2:58 PM
    Wednesday, October 5, 2016 11:24 AM
    Moderator
  • Orchestration will surely solve the problem...any particular reason that you want to avoid it???

    Regards,


    Mandar Dharmadhikari

    • Marked as answer by Heiko Wrede Friday, October 7, 2016 2:58 PM
    Wednesday, October 5, 2016 12:30 PM
    Moderator

All replies

  • Hi ,

    You should use Orchestration here ..nothing wrong with it:)

    Just give a call to the service which will return the endpoint address and then create a dynamic send port to send the message top.

    Regards,


    Mandar Dharmadhikari

    • Marked as answer by Heiko Wrede Friday, October 7, 2016 2:58 PM
    Wednesday, October 5, 2016 11:24 AM
    Moderator
  • Please help us by giving some details on why you can't just use the built in Retry settings on the Send Port.

    Wednesday, October 5, 2016 11:31 AM
    Moderator
  • The build in retry option works only if the send adapter runs on an error.

    If the pipeline (component) throws an exception biztalk does not process the configured retry logic, but it suspended the message. (That's what I find out so far.)

    It is possible to write a custom value to the context property "ActualRetryCount":

    inMsg.Context.Write("ActualRetryCount", http://schemas.microsoft.com/BizTalk/2003/system-properties, newActualValue);

    But that will not prevent the adapter to run, because the Execute-method should return the message to allow any further processing.

    My task is to retry retrieving the target address, not the sending.

    May be an orchestration ist the only possible way?

    Wednesday, October 5, 2016 12:26 PM
  • Orchestration will surely solve the problem...any particular reason that you want to avoid it???

    Regards,


    Mandar Dharmadhikari

    • Marked as answer by Heiko Wrede Friday, October 7, 2016 2:58 PM
    Wednesday, October 5, 2016 12:30 PM
    Moderator
  • You should use Orchestration here ..nothing wrong with it:)

    [...]

    Mandar Dharmadhikari

    ... except the afford to create it ;-) 

    My pipeline is already working. The "possible delay" issue appears unexpected... and I desired to solve it quite simple in the components code.

    To get the retry logic in the Orchestration I have to place a loop shape with the service call and a delay shape in it. Right? (The service call will return something like string.empty if the expected address is not available yet.)

    Is there a way to configure the maxRetryCount and retryIntervalTime parameter via Admin Console like the send port- or pipeline parameter?

    Wednesday, October 5, 2016 12:58 PM
  • Hi,

    The orchestration solution is easy to implement, you probably do not even need a loop if the error in the send port for retrieiving the external address has a communication fault (e.g timeout). When the send port faces a communication fault, it automatically retries and eventually suspends the message and the orchestration.

    On the other hand if the external service returns a soap fault (e.g server internal error) or a valid response, the response is propagated back to the orchestration and the orchestration needs to handle the response/ soap fault error and apply any retry logic. If you want soap faults not to propagate to the orchestration, but remain suspended in the send port (just like a communication fault) you need to uncheck the "Propagate soap fault" check box in  your wcf send port. For details, see https://blogs.msdn.microsoft.com/biztalknotes/2013/02/12/how-to-handle-fault-message-in-biztalk-server/ . So if you choose the option not to propagate soap faults, the send port will handle the retry logic. The only caveat is that the design assumption here is any error , including data errors, can be recovered on retries which may not be valid in all scenarios.

    The ideal solution  would be if your service raises a typed SOAP fault, say ExternalServiceNotAvailailbleFault , and your orchestration handles the  retry logic for this specific fault type. For details, on how to handle typed faults, see https://mohamadhalabi.com/2014/04/06/23/ . For details on how to throw typed faults from a wcf service, see https://chsakell.com/2013/04/07/throwing-and-catching-strongly-types-soap-faults-in-wcf/

    in terms of configuring the retry attempts  and retry interval for the orchestration, can use SSO config store or BRE (business rules engine) or the app setting in biz talk configuration. For details, see https://social.technet.microsoft.com/wiki/contents/articles/6494.biztalk-server-application-configuration-options.aspx

    A pipeline component is usually best suited for message (body and context) parsing operations and not really for invoking external communications. If you did want to write retry logic , you have to implement that within the pipeline component which is separate to the send port retry which kicks off when the port attempts to connect to the external system ( after the pipeline stages are executed ).  So within your pipeline component, you have to implement the retry loop, thread.sleep and  test your solution for scalability


    • Edited by lanax Thursday, October 6, 2016 2:55 AM
    Thursday, October 6, 2016 2:23 AM
  • HI Hieko,

    The Orchestration would just query the endpoint retriver service. keep the retry count there as you wish so the service would be retried that many times, if after those retries the service is still unable to return response to the orchestration, then the orchestration gets the exception which you can always catch to ensure that you get proper tracking of events and completion of the orch....

    That should solve the issue.

    As you say cant afford it...

    I would suggest to build an orch rather than trying out various pipeline scenarios as it will save time and would ensure a proper working solution.

    Regards,


    Mandar Dharmadhikari

    Thursday, October 6, 2016 3:35 AM
    Moderator
  • Hi,

    I got the point to use an Orchestration for this process. It will be one more step for me to take the special way orchestrations work ("special" from a pure C# developers perspective ;-) ).

    Some times later I have a suitable orchestration within my existing Orch-Projekt. Now when I try to deploy it to my local BizTalk 2013 R2, an error occurs.
    I don't know why "System.Web.Services" is needed. I did not ad such reference or implemented code that uses it. Also I wonder at the Version 2.0.0.0 - another biztalk projekt in this solution references ths dll but Version 4.0.0.0.

    Any idea, why this occures? (should I open another question on that?)

    --> Solved!

    Rolled back to the last working code release. Same problem! :-(

    To get the VS 2015 setup working on that machine, one commended me to uninstall the .NET Framework 3.5 and 2.0 Windows feature. That works for the setup. But BizTalk is not amused now.

    Reinstalled the old Framework versions and the orchestration project deployed successfully. :-)

    The output:

    error DEPLOY: Referenced assembly "System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located on local machine's filesystem, so it's impossible to determine if its deployment is required prior to deployment of current assembly MySolution.Orchestrations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7d3f3bf4aa48d586. If referenced assembly is not BizTalk assembly, register it in GAC or add it as a resource to any application in the group using BizTalk Management Console or btstask.exe specifying type "System.BizTalk:Assembly", then try again.
    
    error DEPLOY:    at Microsoft.BizTalk.Deployment.BizTalkAssembly.VerifyModule()
       at Microsoft.BizTalk.Deployment.BizTalkAssembly.PrivateDeploy(String server, String database, String assemblyPathname, String applicationName)
       at Microsoft.BizTalk.Deployment.BizTalkAssembly.Deploy(Boolean redeploy, String server, String database, String assemblyPathname, String group, String applicationName, ApplicationLog log)
    
    error DEPLOY: Referenced assembly "System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located on local machine's filesystem, so it's impossible to determine if its deployment is required prior to deployment of current assembly MySolution.Orchestrations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7d3f3bf4aa48d586. If referenced assembly is not BizTalk assembly, register it in GAC or add it as a resource to any application in the group using BizTalk Management Console or btstask.exe specifying type "System.BizTalk:Assembly", then try again.
    
    
        : PerformingEndChangeRequestsWithRollBack
    
    error DEPLOY: Failed to add resource(s). Change requests failed for some resources. BizTalkAssemblyResourceManager failed to complete end type change request. Referenced assembly "System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located on local machine's filesystem, so it's impossible to determine if its deployment is required prior to deployment of current assembly MySolution.Orchestrations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7d3f3bf4aa48d586. If referenced assembly is not BizTalk assembly, register it in GAC or add it as a resource to any application in the group using BizTalk Management Console or btstask.exe specifying type "System.BizTalk:Assembly", then try again. 
    
    ========== Build: 2 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
    ========== Deploy: 1 succeeded, 1 failed, 0 skipped ==========



    • Edited by Heiko Wrede Friday, October 7, 2016 3:11 PM added Solution for the offtopic problem
    Friday, October 7, 2016 12:29 PM