none
How to Get the created Request Activity Status using SCSM 2012 SDK

    Question

  • Hi, i have created a ServiceRequest,

    so there are Activities related to Servicerequest.

    I am trying to know the Status of the each Activity (Completed,Failed etc)

    and the Change of Activity (like from ReviewActivity to RunBookActivity).

    how can we get the Activity status change programmatically.

    so that i could Display this Status to other Portal, 

    I am Creating a CustomActivity with ActivityID as Parameter to Workflow inheriting WorkflowActivityBase

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

    {}

    Is this a Right Approach..???


    Plz respond as m not getting the way ..

    • Changed type Shiladitya_s Tuesday, April 10, 2012 1:29 PM It is a Question not Discussion.
    • Edited by Shiladitya_s Thursday, April 12, 2012 12:58 PM to show my Progress on this Question.
    Tuesday, April 10, 2012 1:28 PM

Answers

  • I'm not entirely clear on what you're trying to accomplish, but I can give you some guidance on getting the status of activities that are part of a service request.

    Quick overview before we get to the code: After we connect to the database we want to retrieve some management packs, a relationship, and a type projection. We then want to create some criteria for querying the Service Manager database. Then we execute the query and traverse the results, displaying the activity ID and it's status.

    //Connect to Service Manager
    EnterpriseManagementGroup emg = new EnterpriseManagementGroup("<your management server>");
    
    //Get some management packs
    ManagementPack mpSystem = emg.ManagementPacks.GetManagementPack(SystemManagementPack.System);
    ManagementPack mpSRLib = emg.ManagementPacks.GetManagementPack("ServiceManager.ServiceRequest.Library", mpSystem.KeyToken, new Version("7.5.1464.0"));
    ManagementPack mpWorkItemLibrary = emg.ManagementPacks.GetManagementPack("System.WorkItem.Library", mpSystem.KeyToken, new Version("7.5.1464.0"));
    ManagementPack mpActivityLib = emg.ManagementPacks.GetManagementPack("System.WorkItem.Activity.Library",mpSystem.KeyToken,new Version("7.5.1464.0"));
    
    //Get the relationship and type projection we'll be using for this query
    ManagementPackRelationship mprWIContainsActivity = mpActivityLib.GetRelationship("System.WorkItemContainsActivity");
    ManagementPackTypeProjection mptpWIActivities = mpSRLib.GetTypeProjection("System.WorkItem.ServiceRequestAndActivityViewProjection");
    
    //This is the work item (such as a service request) ID that we're looking for
    String WorkItemID = "SR123";
    
    //Setup the criteria. This will instruct service manager to "Get me the service request with ID SR123"
    String strWICriteria = String.Format(@"
        <Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">
          <Reference Id=""System.WorkItem.Library"" PublicKeyToken=""{0}"" Version=""{1}"" Alias=""WILib"" />
          <Expression>
            <SimpleExpression>
              <ValueExpressionLeft>
                <Property>$Target/Property[Type='WILib!System.WorkItem']/Id$</Property>
              </ValueExpressionLeft>
              <Operator>Equal</Operator>
              <ValueExpressionRight>
                <Value>" + WorkItemID + @"</Value>
              </ValueExpressionRight>
            </SimpleExpression>
          </Expression>
        </Criteria>
        ", mpWorkItemLibrary.KeyToken, mpWorkItemLibrary.Version.ToString());
    
    //Build the projection criteria
    ObjectProjectionCriteria opcWI = new ObjectProjectionCriteria(strWICriteria, mptpWIActivities,emg);
    //Perform the query
    IObjectProjectionReader<EnterpriseManagementObject> oprWIs = emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(opcWI,ObjectQueryOptions.Default);
    
    //oprWIs contains all of the work items with ID "SR123" (and there will only be one work item with that ID)
    //We loop through all the work items in the oprWIs collection
    foreach (EnterpriseManagementObjectProjection emopWI in oprWIs)
    {
        //Next we loop through all of the activities contained by our work item, using the WorkItemContainsActivity relationship
        //NOTE that these activities are in no particular order. You'll have to use the icpActivity.Object[null,"SequenceId"].Value to order them
        foreach (IComposableProjection icpActivity in emopWI[mprWIContainsActivity.Target])
        {
            //Since activity status is an enumeration, we want to display it's displayname, not it's value (enumeration values are just GUIDs or other unique identifiers)
            ManagementPackEnumeration status = (ManagementPackEnumeration)icpActivity.Object[null, "Status"].Value;
            //For this little snippet, we're just outputting the activity ID and it's status
            Console.WriteLine(icpActivity.Object[null,"Id"].Value + " " + status.DisplayName);
        }
    }

    Regarding the rest of your post, I'm not sure what you meant when you said you wanted the "change of activity". Are you trying to display the time that an activity's status changed (stored in the activity's history records)?

    Second, if you're displaying this information on some other custom portal, what is the purpose for the workflow?

    A couple disclaimers: Use this code at your own risk, there are no guarantees, etc etc :) Second, I'm assuming you're on Service Manager 2012 RC at least (otherwise the "versions" in the code will need to be changed)

    Are you new to the SCSM SDK? If so, this code snippet might seem overwhelming. I recommend reading the Service Manager blog to get an idea about how classes, objects, relationships, type projections, etc all work.

    Here's a link to a post by Travis that uses the SDK..he also references a lot of the information necessary to best understand Service Manager's inner workings :)
    http://blogs.technet.com/b/servicemanager/archive/2010/10/04/using-the-sdk-to-create-and-edit-objects-and-relationships-using-type-projections.aspx

    • Marked as answer by Shiladitya_s Tuesday, June 26, 2012 2:57 PM
    Friday, April 13, 2012 10:06 PM

All replies

  • I'm not entirely clear on what you're trying to accomplish, but I can give you some guidance on getting the status of activities that are part of a service request.

    Quick overview before we get to the code: After we connect to the database we want to retrieve some management packs, a relationship, and a type projection. We then want to create some criteria for querying the Service Manager database. Then we execute the query and traverse the results, displaying the activity ID and it's status.

    //Connect to Service Manager
    EnterpriseManagementGroup emg = new EnterpriseManagementGroup("<your management server>");
    
    //Get some management packs
    ManagementPack mpSystem = emg.ManagementPacks.GetManagementPack(SystemManagementPack.System);
    ManagementPack mpSRLib = emg.ManagementPacks.GetManagementPack("ServiceManager.ServiceRequest.Library", mpSystem.KeyToken, new Version("7.5.1464.0"));
    ManagementPack mpWorkItemLibrary = emg.ManagementPacks.GetManagementPack("System.WorkItem.Library", mpSystem.KeyToken, new Version("7.5.1464.0"));
    ManagementPack mpActivityLib = emg.ManagementPacks.GetManagementPack("System.WorkItem.Activity.Library",mpSystem.KeyToken,new Version("7.5.1464.0"));
    
    //Get the relationship and type projection we'll be using for this query
    ManagementPackRelationship mprWIContainsActivity = mpActivityLib.GetRelationship("System.WorkItemContainsActivity");
    ManagementPackTypeProjection mptpWIActivities = mpSRLib.GetTypeProjection("System.WorkItem.ServiceRequestAndActivityViewProjection");
    
    //This is the work item (such as a service request) ID that we're looking for
    String WorkItemID = "SR123";
    
    //Setup the criteria. This will instruct service manager to "Get me the service request with ID SR123"
    String strWICriteria = String.Format(@"
        <Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">
          <Reference Id=""System.WorkItem.Library"" PublicKeyToken=""{0}"" Version=""{1}"" Alias=""WILib"" />
          <Expression>
            <SimpleExpression>
              <ValueExpressionLeft>
                <Property>$Target/Property[Type='WILib!System.WorkItem']/Id$</Property>
              </ValueExpressionLeft>
              <Operator>Equal</Operator>
              <ValueExpressionRight>
                <Value>" + WorkItemID + @"</Value>
              </ValueExpressionRight>
            </SimpleExpression>
          </Expression>
        </Criteria>
        ", mpWorkItemLibrary.KeyToken, mpWorkItemLibrary.Version.ToString());
    
    //Build the projection criteria
    ObjectProjectionCriteria opcWI = new ObjectProjectionCriteria(strWICriteria, mptpWIActivities,emg);
    //Perform the query
    IObjectProjectionReader<EnterpriseManagementObject> oprWIs = emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(opcWI,ObjectQueryOptions.Default);
    
    //oprWIs contains all of the work items with ID "SR123" (and there will only be one work item with that ID)
    //We loop through all the work items in the oprWIs collection
    foreach (EnterpriseManagementObjectProjection emopWI in oprWIs)
    {
        //Next we loop through all of the activities contained by our work item, using the WorkItemContainsActivity relationship
        //NOTE that these activities are in no particular order. You'll have to use the icpActivity.Object[null,"SequenceId"].Value to order them
        foreach (IComposableProjection icpActivity in emopWI[mprWIContainsActivity.Target])
        {
            //Since activity status is an enumeration, we want to display it's displayname, not it's value (enumeration values are just GUIDs or other unique identifiers)
            ManagementPackEnumeration status = (ManagementPackEnumeration)icpActivity.Object[null, "Status"].Value;
            //For this little snippet, we're just outputting the activity ID and it's status
            Console.WriteLine(icpActivity.Object[null,"Id"].Value + " " + status.DisplayName);
        }
    }

    Regarding the rest of your post, I'm not sure what you meant when you said you wanted the "change of activity". Are you trying to display the time that an activity's status changed (stored in the activity's history records)?

    Second, if you're displaying this information on some other custom portal, what is the purpose for the workflow?

    A couple disclaimers: Use this code at your own risk, there are no guarantees, etc etc :) Second, I'm assuming you're on Service Manager 2012 RC at least (otherwise the "versions" in the code will need to be changed)

    Are you new to the SCSM SDK? If so, this code snippet might seem overwhelming. I recommend reading the Service Manager blog to get an idea about how classes, objects, relationships, type projections, etc all work.

    Here's a link to a post by Travis that uses the SDK..he also references a lot of the information necessary to best understand Service Manager's inner workings :)
    http://blogs.technet.com/b/servicemanager/archive/2010/10/04/using-the-sdk-to-create-and-edit-objects-and-relationships-using-type-projections.aspx

    • Marked as answer by Shiladitya_s Tuesday, June 26, 2012 2:57 PM
    Friday, April 13, 2012 10:06 PM
  • Hi Aaron,

    The above Post is really help full, Actually there is a Sharepoint Portal from where user can create Service Request so the SR is having Activities related to it, wht i need is that as the Activities are Changing lik "RA123" Status - (pending , Approved) and then next Activity as RB245 Status (.....) so simultaneously i want to show the details of the Activity Status to the User on Sharepoint Portal , i was thinking that there must be som Event related to Activity so each time new Activity from (RA to RB) get change so i can fire the Status of the Previous Activity to the Portal.

    Thats Why i was looking at the Workflow Event

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

    {}

    I have created the Custom Activity and i bind it with the Management Pack and each time the Status of Activity i was collecting frm the above  event. But i hope your above code is showing an another approach to get that functionality. Let me try your above solution . I am not completely new to SCSM SDk yeah But learning.                                                                                                                                                

    Monday, April 16, 2012 5:47 AM
  • I believe I see what you're doing.  You're updating your sharepoint portal based on an "event", correct? (I did something similar with a custom web page, but I just had some javascript refresh the page every 30 seconds :) ).

    The code I proposed above will give you access to the status of all of the activities within a given service request (or any work item). However, the code uses a service request ID in the query criteria. Since your event will be based off of an activity change, you will have to send the activity's parent work item ID as a parameter to your custom workflow. (Basically, the "context" of your event is an activity. So you need information related to the context). If I understand your scenario correctly, you'll have a workflow rule that executes your custom workflow anytime an activity's status field changes. So your workflow parameter will look something like this:

    $Context/Path[Relationship='ActivityLib!System.WorkItemContainsActivity' SeedRole='Target']/Property[Type='WILib!System.WorkItem']/Id$

    Basically telling service manager to send the triggering activity's parent work item ID as a paramter to your workflow. (this is not exactly what the string will look like! your references may be different :) )

    So, after your workflow has all of the activities and activity statuses (using the code above), you'll populate your sharepoint page with that information. Keep in mind that the code I presented above will not necessarily present the activities in the correct order! It would be best if you order them yourself using the SequenceId property.

    As for building a custom workflow, in case you haven't seen this post:
    http://blogs.technet.com/b/servicemanager/archive/2010/05/06/incident-sla-management-in-service-manager.aspx

    There are some very good details about how to build a custom workflow with the SDK in C#..the demo project itself is unrelated, but it provides the workflow framework for building your own activities. (Alternatively, if you want to skip the authoring tool, you can create any normal windows workflow foundation workflow and have it executed from a service manager rule simply by referencing your workflow assembly directly. It will accept custom parameters and everything :) )

    Let me know how it goes :)

    Monday, April 16, 2012 2:46 PM
  •             This is glimpses of code, which might be help you, to find the status of Incident.

               string strCriteria = @"<Criteria xmlns='http://Microsoft.EnterpriseManagement.Core.Criteria/'>
                <Reference Id='System.WorkItem.Library' PublicKeyToken='{0}' Version='{1}' Alias='WorkItem' />
                <Expression>
                <SimpleExpression>
                <ValueExpressionLeft>
                <Property>$Context/Property[Type='WorkItem!System.WorkItem']/Id$</Property>
                </ValueExpressionLeft>
                <Operator>Like</Operator>
                <ValueExpressionRight>
                <Value>%</Value>
                </ValueExpressionRight>
                </SimpleExpression>
                </Expression>

                </Criteria>";
                ManagementPackCriteria mpCr = new ManagementPackCriteria("Name = 'System.WorkItem.ReleaseRecord.Library'");
                IList<ManagementPack> mps = emGroup.ManagementPacks.GetManagementPacks(mpCr);

                ManagementPackClassCriteria classCr = new ManagementPackClassCriteria("Name = 'System.WorkItem.ReleaseRecord'");
                IList<ManagementPackClass> classes = emGroup.EntityTypes.GetClasses(classCr);

                if (mps != null && mps.Count > 0 && classes != null && classes.Count > 0)
                {
                    ManagementPack mp = mps[0];
                    ManagementPackClass cl = classes[0];
                    // For all system management packs version and KeyToken are same.
                    EnterpriseManagementObjectCriteria cr = new EnterpriseManagementObjectCriteria(string.Format(strCriteria, mp.KeyToken, mp.Version), cl, mp, emGroup);
                    IObjectReader<EnterpriseManagementObject> reader = emGroup.EntityObjects.GetObjectReader<EnterpriseManagementObject>(cr, ObjectQueryOptions.Default);
                        foreach (EnterpriseManagementObject obj in reader)
                        {
                            MessageBox.Show(obj[null, "Status"].Value.ToString());
                            if (obj[null, "Status"].Value.ToString() == "ReleaseStatusEnum.Editing")
                            {
                                if (ctr <= counter)
                                {
                                    dr[0] = obj[null, "Id"].Value.ToString();
                                    dr[1] = obj[null, "Title"].Value.ToString();
                                    dr[2] = Convert.ToDateTime(obj[null, "CreatedDate"].Value.ToString()).ToShortDateString();
                                    nowDate = DateTime.Now;
                                    span = nowDate.Subtract(Convert.ToDateTime(obj[null, "CreatedDate"].Value.ToString()));
                                    dr[3] = Convert.ToInt32(span.Days.ToString());
                                    dtIncident.Rows.Add(dr);
                                    dr = dtIncident.NewRow();
                                    ctr++;
                                }
                                else
                                {
                                    ctr++;
                                }
                            }


                        }

                                                               

    scsm 2012 answer

    Tuesday, June 26, 2012 7:57 AM
  • It's been just few hours that I have started learning about service manager sdk 2012, I would like to know how will we catch the service request in C# application as soon as it is created in SCSM.

    Thank you,

    Kshamesh

    Thursday, February 27, 2014 3:52 PM