Ask a questionAsk a question
 

QuestionWorflow / Web services / Samples

  • Wednesday, June 03, 2009 12:16 PMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi all,
     It looks like the Azure worflow samples and doc have not been updated with the latest Azure tools development.
    Or is it just that I am not looking at the rigth place?

    I'm willing to create a simple worflow scenario extracting the init parameters from the HTTP request, storing them as worflow variables and using them along the scenario.
    Very easy indeed.

    But not that easy using the worflow UI ...

    Any idea?

    Thanx,

    --mike
    • Edited byptimilo Friday, June 05, 2009 12:49 PM
    •  

All Replies

  • Wednesday, June 03, 2009 3:27 PMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok I have other questions. Can't really find a real answer ...

    Ideally, I'd like to create a worflow on the cloud based on .net web services (deployed on the cloud using Azure tools).
    I'd like to start the worflow by sending an HTTP request from a simple http client. This HTTP request would contain an ID which I'd like to pass along the worflow to my web services (as input parameter).

    I read somewhere that it is not possible to deploy WF worflows on the Cloud. Is that true?
    If not, I read that my web services had to speak REST to ease their invocation. Are web services (web roles) speaking REST by default?

    Do I need at all the Service Bus if my worflow is based on Cloud web services?
    All the worflow samples use SB services. Is that mandatory?

    I'm still looking fro a comprehensive doc.

    I'm lost. Thanx,

    --mike
  • Wednesday, June 03, 2009 3:41 PMBrentDaCodeMonkey Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Your web services do not HAVE to be REST based. its your interface, your implement it. You can toss a traditional .NET web service up if that's what you want. You don't need the service bus unless you want too. That's why all these pieces of Microsoft Azure Services are seperate components. Allows you to use an ala-carte model so you only consume the pieces you want too. The Service Bus does have a WF component, but unfortunately I can't speak to full WF support in an Azure worker or web role. 
  • Wednesday, June 03, 2009 6:45 PMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Your web services do not HAVE to be REST based. its your interface, your implement it. You can toss a traditional .NET web service up if that's what you want. You don't need the service bus unless you want too. That's why all these pieces of Microsoft Azure Services are seperate components. Allows you to use an ala-carte model so you only consume the pieces you want too. The Service Bus does have a WF component, but unfortunately I can't speak to full WF support in an Azure worker or web role. 
    That's what I meant with the REST wrapping. So you confirm that the wbs have to talk REST to be used in Azure Worflow? The worflow samples are confusing 'cos they only use SB services so in the end I was really wondering if it was at all possible. And using the VS UI to build worflow and bind my webs is not easy at all. And the doc (at least the one I found) is not helpfull. Anybody has a good pointer? I intend to use the SB to mix on-premise and Cloud services in the future. Thanx anyway for your answers.
  • Thursday, June 04, 2009 8:12 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello, so as I understand, you want to leverage WF in Windows Azure, and the workflow will in turn call a web service, correct? In this case, I think you can use normal WF without .NET Services. Today cloud workflow is quite limited, and cannot be extended. However, Windows Workflow Foundation is fully supported in Windows Azure, as long as your role is configured to support full trust.

    Below is a quick sample:

    Create a normal WCF service in your web role. This is just a sample. You can of course host the service out of Windows Azure. For example, the service can be hosted on-premise and exposed to Internet via Service Bus. I'm using the following simple contract:

    [

    ServiceContract]

     

    public interface IServiceToBeCalledByWF

    {

    [

    OperationContract]

     

    void DoWork(string name);

    }

     

    Create a new Sequential Workflow Library project. Add a service reference to your WCF service. Then modify the app.config so the endpoint address points to http://127.0.0.1:81(or yourname.cloudapp.windows.net)/yourservice.svc.

    Drop a SendActivity onto the designer surface.

    Click the "..." Button in the SendActivity's ServiceOperationInfo property.

    In the Choose Operation dialog, click Import.

    You should see IServiceToBeCalledByWF from your service reference listed in the dialog. Select it and click OK twice.

    For the ChannelToken and EndpointName properties, type the endpoint name in your app.config. For example, if the endpoint looks like this:

    <

    endpoint name="BasicHttpBinding_IServiceToBeCalledByWF" .../>

    Type BasicHttpBinding_IServiceToBeCalledByWF for the properties.

    For the name parameter of the service operation, bind it to a new DependencyProperty. I'm going to call the property NameParameter. We'll pass the value of this property from the hosting application. For example, pass a query string's value to this property.

     

    Now the workflow project is ready. Switch back to the web role. First thing to do is to copy the service client configuration from WF library's app.config to web role's web.config. Since you're in web role, web.config will be used instead of app.config.

    <

    client>

    <

    endpoint address="http://127.0.0.1:81/ServiceToBeCalledByWF.svc"

     

    binding="basicHttpBinding"

     

    contract="ServiceReference1.IServiceToBeCalledByWF" name="BasicHttpBinding_IServiceToBeCalledByWF" />

    </

    client>

     

    Enable full trust for the web role. WF requires full trust.

    <

    WebRole name="WebRole" enableNativeCodeExecution="true">

     

    Add a reference to your WF library in your web role, as well as WF related assemblies.

    Create a Global.asax, and start the workflow runtime in Application_Start:

     

    protected void Application_Start(object sender, EventArgs e)

    {

     

    WorkflowRuntime workflowRuntime = new WorkflowRuntime();

    workflowRuntime.StartRuntime();

    Application[

    "WorkflowRuntime"] = workflowRuntime;

    }

     

    Now you can start a workflow instance whenever you like. For example, in Default.aspx:

     

    protected void Page_Load(object sender, EventArgs e)

    {

     

    string name = Request.QueryString["name"];

     

    if (!string.IsNullOrEmpty(name))

    {

     

    WorkflowRuntime workflowRuntime = (WorkflowRuntime)Application["WorkflowRuntime"];

     

    Dictionary<string, object> parms = new Dictionary<string, object>();

     

    //The key must be the DependencyProperty's name in your workflow.

    parms.Add(

    "NameParameter", name);

     

    WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow(typeof(Workflow1), parms);

    workflowInstance.Start();

    }

    }

     

    I have written a quick sample on http://cid-4722d155fb172dbb.skydrive.live.com/self.aspx/Public/Azure/CloudNormalWF.zip. You can have a look if you like. Run the application, and type something like http://127.0.0.1:81/?name=Lante. You will see a log like the following (in WCF I'm simply writing the name to log). Note it may take quite a few seconds for the log to display during the first request due to WCF cold start.

    08:04:32:770,Event=Information,Level=Info,ThreadId=53984,=Lante

     


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Thursday, June 04, 2009 12:48 PMBrentDaCodeMonkey Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanks for the response Yi-Lun, I figured/hoped this was the case but since I hadn't tried it myself, I was hesitent to comment on it.

    Glad to hear it works as I had hopped.
  • Friday, June 05, 2009 8:09 AMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello, so as I understand, you want to leverage WF in Windows Azure, and the workflow will in turn call a web service, correct? In this case, I think you can use normal WF without .NET Services. Today cloud workflow is quite limited, and cannot be extended. However, Windows Workflow Foundation is fully supported in Windows Azure, as long as your role is configured to support full trust.

    Thank you very much for your answer.

    All I want to do is some worflow on the Cloud. The worflow would be orchestrating on legacy .net web services which I uploaded on Azure.

    If I understand you correctly, I should not use the "Cloud WF" but the normal one and re-write my web services as WCF ones.
    Right?

    In your sample, is the web service (WCF? web role?) uploaded into the Cloud? My all point is to upload some of our techno in the cloud so it would be a pity to have it run locally in the end ;-)
    If so, would it be accessible separately (not from the worflow) as any real .Net web service?

    Also, in your sample, how do you upload the workflow in the cloud since it is not available from the normal WF editor ... or is it that we can create normal workflows using the "Cloud workflow" editor (the one that has the right click menu 'upload in the cloud')?

    And last, when we talk about SB services, does this mean they are not running in the Cloud?

    Thanx again.


    • Edited byptimilo Friday, June 05, 2009 12:47 PM
    •  
  • Monday, June 08, 2009 8:31 AMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Anybody?
  • Monday, June 08, 2009 9:40 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Yes, the web service is uploaded to the cloud, inside a web role. You can access it with the cloud url, such as http://yourname.cloudapp.net/yourservice.svc. SendActivity is used to invoke WCF services. You can also access legacy ASMX services using WebServiceInvokeActivity.

    You need to create a normal Sequential Workflow Library project, and use the normal WF designer to create the workflow. Then reference the library in your web role.

    Services exposed by Service Bus are still running on your on-premise servers. But without Service Bus, you will have to buy a domain if you want the service to be visible to Internet. Also you have to configure your firewall to allow the service to exchange messages, unless you host the service on a standard web server such as IIS which uses standard ports. With Service Bus, your service will be visible to Internet (so you can call it from everywhere such as a project running in the cloud) without buying a domain. It also allows you to communicate using the standard port such as 80 and 443, so you don't need to worry about firewall issues.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Monday, June 08, 2009 3:41 PMSANMI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi! I have done a normal Sequential Workflow Library to create the workflow. It invokes ASMX services (WebServices) using WebServiceInvokeActivity.

    I have an error when I start a workflow instance:

    protected void Page_Load( object sender, EventArgs e)

    {

       string name = Request.QueryString[ "name" ];

       if (! string .IsNullOrEmpty(name))

       {

           WorkflowRuntime workflowRuntime = ( WorkflowRuntime )Application[ "WorkflowRuntime" ];

           Dictionary < string , object > parms = new Dictionary < string , object >();

           //The key must be the DependencyProperty's name in your workflow.

          parms.Add("NameParameter" , name);

          WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow( typeof ( Workflow1 ), parms);      -> ERROR: Object reference not set to an instance of an object.

          workflowInstance.Start();

       }

    }

    I have done the same... I don't understand, can you help me?
  • Tuesday, June 09, 2009 10:02 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    What is null? Do you have a stack trace? Just a guess. Maybe workflowRuntime is null. Have you put Application["WorkflowRuntime"] = workflowRuntime;  in Application_Start?
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Tuesday, June 09, 2009 1:43 PMSANMI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok, I hadn't the Global.asax because I don't find how can I add it. What type of project is it? I solve my error with an import of your Global.asax but it isn't a good form...

    Now, I want to introduce with this normal workflow ASMX Services "web service" (as I have done) and service on-premise with the service bus. Is it possible with the normal workflow? What is the workflow activity to use this service on-premise? (SendActivity??)

    Thank you!
    • Edited bySANMI Tuesday, June 09, 2009 4:08 PMAdd new questions
    •  
  • Wednesday, June 10, 2009 6:05 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    In your web role project, you can add a new item. Select the "Global Application Class" item template in Visual Studio, and it will create the Global.asax for you.

    For the second question, do you mean you want to expose you ASMX service hosted locally to the internet using service bus? Service bus only supports WCF. So you'll have to switch to WCF. To work with service bus from a normal workflow, you will have to use Basic/WSHttpRelayBinding, and turn off ACS by setting RelayClientAuthenticatinMode to None. Then you can use a normal SendActivity to work with the service. You will not be able to use CloudServiceBusSendActivity in a normal workflow. Even if you can, if you don't turn off ACS, you will not be able to provide the credentials in the workflow.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
  • Wednesday, June 10, 2009 7:38 AMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Thanx.
    No the on premise service will be WCF compliant. The questionment we had was weather or not it was possible to invoke sb services from a 'normal' worflow and also mix sb and ASMX services call in that worflow.

    From what I undersand, yes it is possible, providing we apply the configuration you mentionned.

    Thanx again.

    --mike
  • Thursday, June 11, 2009 10:04 AMSANMI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Ok, good answer Yi-Lun Luo!

    But my web role project hasn't as item "Global Application Class"... What could I download to have it?

    In my project, I have a workflow that invoke an Web Services with parameters of return. How can I get this parameters from the client who create the workflow? What's the activity to do it?

    Thank you!
  • Friday, June 12, 2009 9:25 AMSANMI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello! I tried to practice your answers, but I have doubts about how can I mix the workflow, with the bus service and service on-premise, could you help me? As for Windows Azure, each step requires a different way to do it, I do not know a guide which I could use.

    My idea is a WCF service in local that use a bus service to communicate with the workflow that will be in the cloud.

    Thank you very much
  • Thursday, June 18, 2009 3:07 PMSANMI Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi!! If Yi-Lun Luo can't answer, anybody could do it?


    To sum up:
    - My web role project hasn't as item "Global Application Class"... What could I download to have it?
    - What's the
    activity to use to return something from the workflow?
    - How to invoke SB services from our “normal” workflow? How can I mix the workflow, with the bus service and service WCF on-premise?

    Thanks!!

  • Monday, June 22, 2009 6:28 AMptimilo Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Anybody?
  • Monday, June 22, 2009 9:01 AMYi-Lun LuoMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    ptimilo, are you having the same problem as SANMI? If not, I would suggest SANMI to open a new thread since we're no longer discussing the original problem.

    Anyway, "Global Application Class" is provided in Visual Studio out of box for all ASP.NET projects. Can you make sure you're trying to add it in the web role project (not the cloud service or workflow project)? Also make sure you're selecting the "Web" or "Visual C#" tab in the "Add New Item" dialog. If your project already contains a Global.asax, you will not see this item template because Global.asax must be unique for each web project.

    To return the result from the web service, you just bind the (Return Value) to a new property in the workflow's code behind:

    <

     

    WorkflowParameterBinding ParameterName="(ReturnValue)">

    <

     

    WorkflowParameterBinding.Value>

    <

     

    ActivityBind Name="Workflow1" Path="ReturnValue" />

    </

     

    WorkflowParameterBinding.Value>

    </

     

    WorkflowParameterBinding>



    [

    DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]

    [

    BrowsableAttribute(true)]

    [

    CategoryAttribute("Parameters")]

     

    public string ReturnValue

    {

     

    get

    {

     

    return ((string)(base.GetValue(WorkflowLibrary2.Workflow1.ReturnValueProperty)));

    }

     

    set

    {

     

    base.SetValue(WorkflowLibrary2.Workflow1.ReturnValueProperty, value);

    }

    }



    Then modify the code behind of the aspx page to the following:

     

    private ManualResetEvent manualResetEvent = new ManualResetEvent(false);

     

    protected void Page_Load(object sender, EventArgs e)

    {

     

    string name = Request.QueryString["name"];

     

    if (!string.IsNullOrEmpty(name))

    {

     

    WorkflowRuntime workflowRuntime = (WorkflowRuntime)Application["WorkflowRuntime"];

     

    //The key must be the DependencyProperty's name in your workflow.

     

    Dictionary<string, object> parms = new Dictionary<string, object>();

    parms.Add(

    "NameParameter", name);

     

    WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow(typeof(Workflow1), parms);

    workflowInstance.WorkflowRuntime.WorkflowCompleted +=

    new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);

    workflowInstance.Start();

    manualResetEvent.WaitOne();

    }

    }

     

    void WorkflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)

    {

    manualResetEvent.Set();

    Response.Write(e.OutputParameters[

    "ReturnValue"]);

    }



    You need a ManualResetEvent because workflow instances are invoked asynchronously, and you need to wait for it to complete before returning the response to the client. Any public properties in your workflow's code behind can be accessed in WorkflowCompletedEventArgs.OutputParameters.

    To invoke a service hosted on the service bus, just set relayClientAuthenticationType to None on the binding on the service side, so you can bypass ACS. Then it is the same as working with a normal WCF service.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.