Starting K2 Process from a Web Service and vice-versa
15 December 08 05:29 PM | Joseph | 0 Comments   

Starting a K2 process from .net code is very simplistic, so it is just as easy to do so from any of your .net projects including web services.

 Attached is a solution containing:

- a web service that can start a process under the credentials you specify

- a process and referenced smartobject containing a client event for the form included and an optional web service call to demonstrate how to go full circle back to the web service

- a customized version of the SampleK2Form (blackmarket) that can also start a new instance of the included "Generic Process" and interact with the client event within the process allowing you to spawn additional process instances via the web service

** When you deploy the form, deploy to a Virtual Directory called "SampleK2Form" under your k2 web server's workspace Virtual Directory
*** When you deploy the web service, deploy to a Virtual Directory called "K2ProcessCalls" under your k2 web server's workspace Virtual Directory

Have fun :)
Joseph

Attachment(s): K2ProcessCalls.zip
DLL Debugging Via K2HostServer
24 November 08 10:22 AM | Joseph | 0 Comments   

Blackpearl's K2HostServer.exe (the heart of the operation) is very elegant at surfacing any of your references while debugging.  All you must do is attach the project you want to debug, insert your stop point, attach to "K2HostServer.exe and if the project's code is utilized by Blackpearl, you will get to step through.   I have always had the best responses from this system when using GAC'd dlls or DLLs that have been strongly named via a key and added to c:\windows\assembly on the K2 Server.  Taking this approach has other advantages too which are open for debate and belong on another Blog somewhere.

In short, the attached document walks you through creating a simple library, including it a sample K2 process and debugging as the process utilizes the library.  This library for the project I'm currently on is planned to leverage the Workflow.Client dll for making local calls to the K2 Server and thus, I have posted this example in this forum.

Have a happy Thanksgiving!!!
:)
Joseph

Delegation with workflow client
12 September 08 09:27 AM | Joseph | 0 Comments   

When you first explore the WorklistItem.Delegate() method you might be put off by the fact that it requires a Destinations or Destination object in order to do it's work.  Well never fear, here are some methods you can leverage to quickly get this feature integrated into your client event forms:

You'll need a few references and using statements for this code to work

using SourceCode.Hosting.Server.Interfaces;
using SourceCode.Security.UserRoleManager.Client;
using SourceCode.Workflow.Client;

This is an excerpt from my Page_Load() method within my switch statement that is based on page state (look for a future post that discusses creating a page state object and a method to match it)  This code could be included in the method executed by your Delegate button or in another aspx form or ...  wherever you want it to be.  Note that I'm declaring a few private variables before the page_load method for use throughout my methods:

Declarations before PageLoad
SourceCode.Workflow.Client.Connection m_oConn = null; 
//bp server from the web.config
private string m_strBPServer = System.Configuration.ConfigurationManager.AppSettings["WorkflowServer"];

Open the connection at the beginning of PageLoad
          // open the connection
            m_oConn.Open(m_strBPServer);

After deriving the state and getting into my switch statement
                 case constState.WorklistItemDelegate:

                    //utilize the resolvetext.. method to split the provided string and resolve to a sourcecode destinations object  //Methods below in this text
                    Destinations oDestinations = ResolveTextToDestination(txtDelegate.Text);
                    //declare a second destinations object to contain the destinations with the action permissions added
                    Destinations oDestinationsWithActions = new Destinations();
                    if (oDestinations.Count != 0)
                    {
                        try
                        {
                            oWli = m_oConn.OpenWorklistItem(GetSerialNumber(), "ASP", false);

                            //provide a readout of each destination and resolved type that is being delegated to
                            lblStatus.Text = "The following have been added to the worklist item's delegation:<Br>";
                           //while providing the readout, assign permission to all available actions, augment this method to allow for ui that let's the user choose which actions to delegate
                           foreach (Destination oDestination in oDestinations)
                            {
                                lblStatus.Text = lblStatus.Text + "<font color=red>" + oDestination.DestinationType.ToString() + ": " + oDestination.Name + "</font><Br>";
                                oDestinationsWithActions.Add(AssignPermissionToAllActions(oDestination, oWli));
                            }

                            //if the worklist item is open, release it so it will show in the default view of delegate worklists
                            if (oWli.Status == WorklistStatus.Open) oWli.Release();

                            //apply the delegation
                            oWli.Delegate(oDestinationsWithActions);

                            //provide the next step for the user 
                            lblStatus.Text = lblStatus.Text + "<Br> To reopen the worklist item <i>(which will remove the item from others' worklists)</i> ";
                            lblStatus.Text = lblStatus.Text + "<a href=" + Request.FilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Click Here</a>";

                            //cleanup
                            Session["m_strProcessName"] = "";
                            hdnSerialNum.Value = "";

                        }
                        catch (Exception eOpenWliException)
                        {
                            lblWhatAmIDoing.Text = "Unable to Delegate";
                            lblStatus.Text = " The worklist could not be delegated<br>" + eOpenWliException.Message.ToString() + "<br>";//;
                            lblStatus.Text = lblStatus.Text + "<a href=" + Request.AppRelativeCurrentExecutionFilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Return to Worklist Item</a>";
                        }
                        finally
                        {
                            m_oConn.Close();
                        }
                    }
                    else
                    {
                        lblStatus.Text = lblStatus.Text + "Unable to delegate to users: '" + txtDelegate.Text + "' did not resolve any useable destinations<br>";
                        lblStatus.Text = lblStatus.Text + "<Br> To reopen the worklist item ";
                        lblStatus.Text = lblStatus.Text + "<a href=" + Request.FilePath.ToString() + "?SN=" + hdnSerialNum.Value + ">Click Here</a>";
                    }
                    break;

 

These methods use a text string passed from the page_load() area, they parse for comma + space and test to see if each entry is a role, ad group or ad user.  There are definitely other ways of accomplishing this more neatly from the UI (drop down lists etc), but this example displays maximum flexibility for handling user input so anything else should be simpler to implement.

        private Destination AssignPermissionToAllActions(Destination oDestination, WorklistItem oWli)
        {
            foreach (Action oAction in oWli.Actions)
            {
                oDestination.AllowedActions.Add(oAction.Name);
            }
            return oDestination;
        } 


        private Destinations ResolveTextToDestination(string strDelegateText)
        {
            //split the incoming string into a string array of possible destinations
            string[] strDestinations = Regex.Split(strDelegateText, ", ");

            //declare a destinationS object to pass back to the calling method
            Destinations oDestinations = new Destinations();

            //for loop over the incoming destinations string array
            for (int i = 0; i < strDestinations.Length; i++)
            {
                //clear the temp destination object
                Destination oDestination = new Destination();
                //derive the type of destination and add a destination object to oDestinationS for each one
                oDestination = TestDestinationIsARole(strDestinations[i]);
                if (oDestination.Name != string.Empty)
                {
                    oDestinations.Add(oDestination);
                }
                else
                {
                    oDestination = TestDestinationIsAGroup(strDestinations[i]);
                    if (oDestination.Name != string.Empty)
                    {
                        oDestinations.Add(oDestination);
                    }
                    else
                    {
                        oDestination = TestDestinationIsAUser(strDestinations[i]);
                        if (oDestination.Name != string.Empty)
                        {
                            oDestinations.Add(oDestination);
                        }
                    }
                }

            }
            return oDestinations;

        }

        private Destination TestDestinationIsARole(string strDestinationName)
        {//check that role exists by trying to resolve it's queue to an object
            UserRoleManagerServer umClient = new UserRoleManagerServer();
            SCConnectionStringBuilder cb = new SCConnectionStringBuilder();
            Destination oDestination = new Destination();

            //Build a SC Connection String
            cb.Host = m_strBPServer;
            cb.Port = Convert.ToUInt32(m_strBPServerPort);
            cb.Integrated = true;
            cb.IsPrimaryLogin = true;

            //Open the connection to K2
            umClient.CreateConnection();
            umClient.Connection.Open(cb.ToString());

            //Obtain a collection of users for this role
            try
            {
               // IUserCollection roleUsers = ;
                if (umClient.ResolveQueue(strDestinationName) != null)
                {   //Close the Connection
                    umClient.Connection.Close();
                    oDestination.DestinationType = DestinationType.Role;
                    oDestination.Name = strDestinationName;
                    return oDestination;
                }
                else
                {
                    //Close the Connection
                    umClient.Connection.Close();
                    return oDestination;
                }
            }
            catch
            {
                return oDestination;
            }
           
        }

        private Destination TestDestinationIsAGroup(string strDestinationName)
        {
            if (strDestinationName.IndexOf(@"\") == -1) strDestinationName = m_strDefaultADDomain + @"\" + strDestinationName;
            if (strDestinationName.IndexOf(":") == -1) strDestinationName = m_strDefaultLabel + ":" + strDestinationName;
           
           
            UserRoleManagerServer umClient = new UserRoleManagerServer();
            SCConnectionStringBuilder cb = new SCConnectionStringBuilder();
            Destination oDestination = new Destination();

            //Build a SC Connection String
            cb.Host = m_strBPServer;
            cb.Port = Convert.ToUInt32(m_strBPServerPort);
            cb.Integrated = true;
            cb.IsPrimaryLogin = true;

            //Open the connection to K2
            umClient.CreateConnection();
            umClient.Connection.Open(cb.ToString());

            //Obtain a collection of users for this role
            try
            {
                if (umClient.GetGroup(strDestinationName, m_strDefaultLabel, "") != null)
                {   //Close the Connection
                    umClient.Connection.Close();
                    oDestination.DestinationType = DestinationType.Group;
                    oDestination.Name = strDestinationName;
                    return oDestination;
                }
                else
                {
                    //Close the Connection
                    umClient.Connection.Close();
                    return oDestination;
                }
            }
            catch
            {
                return oDestination;
            }
        }

        private Destination TestDestinationIsAUser(string strDestinationName)
        {
            if (strDestinationName.IndexOf(@"\") == -1) strDestinationName = m_strDefaultADDomain + @"\" + strDestinationName;
            if (strDestinationName.IndexOf(":") == -1) strDestinationName = m_strDefaultLabel + ":" + strDestinationName;
            Destination oDestination = new Destination();

            UserRoleManagerServer umClient = new UserRoleManagerServer();
            SCConnectionStringBuilder cb = new SCConnectionStringBuilder();


            //Build a SC Connection String
            cb.Host = m_strBPServer;
            cb.Port = Convert.ToUInt32(m_strBPServerPort);
            cb.Integrated = true;
            cb.IsPrimaryLogin = true;

            //Open the connection to K2
            umClient.CreateConnection();
            umClient.Connection.Open(cb.ToString());

            //Obtain a collection of users for this role
            try
            {
                if (umClient.GetUser(strDestinationName, m_strDefaultLabel, "") != null)
                {   //Close the Connection
                    umClient.Connection.Close();
                    oDestination.DestinationType = DestinationType.User;
                    oDestination.Name = strDestinationName;
                    return oDestination;
                }
                else
                {
                    //Close the Connection
                    umClient.Connection.Close();
                    return oDestination;
                }
            }
            catch
            {
                return oDestination;
            }
        }

Search

Go

This Blog

Tags

No tags have been created or used yet.

Syndication