Resource Actions are a component of the ConSol CM Action Framework. Resource Actions are actions which can be performed for a resource, i.e., an object which is stored in the Resource Pool. The actions can be performed automatically by the system or manually, triggered by an engineer who has the required permissions. You might want to apply Resource Actions for use cases like the following:
You can use the following types of Resource Actions:
Please keep in mind that only engineers who have at least one role with the following access permissions for the respective Resource Type are allowed to use the Resource Actions, i.e., only then will the Activities link be displayed in the Web Client:
Figure 556: ConSol CM Web Client - Resource Action (on resource page)
Resource Actions are defined as Groovy scripts which are stored in the Script and Template section of the Admin Tool.
The execution of Resource Actions can be controlled using condition scripts, i.e., you can implement a condition script which is executed before the execution script of the Resource Action. The execution script is only executed if the condition script returns true.
So there are two types of scripts you have to deal with when you use ConSol CM Resource Actions:
When you want to implement a Resource Action you have to proceed in three steps:
In the following sections, all three steps are explained in detail.
Create a new Admin Tool script of type Resource action. If required, create another script of type Resource condition.
For a detailed explanation of Admin Tool scripts in general, please refer to section Admin Tool Scripts.
Figure 557: ConSol CM Admin Tool - Resource Action script in Scripts section
// this script creates a new ticket for the resource from which the activity is executed, i.e., creates new ticket and links it to resource
// resource - ticket relation must be configured beforehand!
import com.consol.cmas.common.model.ticket.Ticket
import com.consol.cmas.common.model.customfield.Unit
import com.consol.cmas.common.model.resource.*
import com.consol.cmas.common.service.resource.*
import com.consol.cmas.common.model.ticket.Queue
import com.consol.cmas.common.model.resource.meta.*
println 'CreateTicketForResource.groovy started ...'
Ticket newtic = new Ticket()
Queue qu = queueService.getByName("ServiceDesk")
newtic.setQueue(qu)
newtic.setSubject("New Ticket for Resource: " + resource.getId())
newtic.set("helpdesk_standard.priority","low")
// use main contact person of the resource as main contact for the ticket
Unit maincont = new Unit()
def crit = new ResourceRelationWithTargetUnitCriteria()
crit.setResource(resource)
List<ResourceRelationWithTargetUnit> cont_list = resourceRelationService.getByCriteria(crit)
if (cont_list.size() == 0) {
//cmweb.rp.resource.action.no_contact_set has to be configured as label in the AT
return actionScriptResultFactory.getPostAction(PostActionType.FAILURE, "cmweb.rp.resource.action.no_contact_set")
} else {
def cont_rel = cont_list[0]
maincont = cont_rel.getTargetUnit()
}
ticketService.createWithUnit(newtic,maincont)
println 'New Ticket created for resource with ID' + resource.getId()
// link ticket to resource
def resRelationDefCriteria = new ResourceRelationDefinitionCriteria()
resRelationDefCriteria.addDefinitionName("PC_Desktop_to_Ticket_Relation")
def s_res_type = resource.getResourceType()
resRelationDefCriteria.addSourceResourceType(s_res_type)
resRelationDefCriteria.addTargetQueue(qu)
//log.info "resRelationDefCriteria = " + resRelationDefCriteria
//log.info "resRelationDefCriteria.definitionName = " + resRelationDefCriteria.getDefinitionsNames()
def resRelationDef = resourceRelationDefinitionService.getByCriteriaUniqueResult(resRelationDefCriteria)
def resRelation = new ResourceTicketRelation(resRelationDef, resource, newtic)
// log.info "resRelation" + resRelation
resourceRelationService.create(resRelation)
Code example 84: Resource execution script
To create, edit, or delete Resource Actions, open the navigation item Actions in navigation group Resources in the Admin Tool.
To create or add a new action click the Add button and fill-in the required data in the pop-up window (the pop-up window is the same for adding and for editing a resource action).
Figure 558: ConSol CM Admin Tool - Creating a Resource Action
Relation
This script will be executed automatically when a relation to or from a resource of this type is
(The script will not be executed when the comment of a relation is changed.)
Save the action. Then you can assign it to Resource Types. Please see following step.
To assign pre-defined Resource Execution and/or Resource Condition Scripts to Resource Types, the respective manual and/or automatic actions have to be assigned to a Resource Type. Open the navigation item Data Models in navigation group Resources in the Admin Tool. Select the Resource Type you would like to edit and click the Edit button to open the pop-up window where you can assign the Resource Actions. An action might contain only a Resource Execution Script or a Resource Condition Script and a Resource Execution Script.
In the following example (next figure), a manual Resource Action is assigned to the resource type PC_Desktop.
Figure 559: ConSol CM Admin Tool - Assigning manual Resource Actions to a resource type
You can assign Resource Actions of the following action types:
As an engineer (user), two Resource Action types are relevant for you because they are available as activities in the Web Client:
The CREATE, UPDATE, RELATION, and DELETE actions run in the background.
Please read the section about Scripts for the Action Framework for a general introduction about important principles, classes, and methods for execution and condition scripts.
Use case: The engineer should be able to create a new Service Desk ticket directly from a resource page of a PC. The new ticket should be related to the resource (PC). The main contact of the new Service Desk ticket should be the person who is responsible for the PC. This is implemented as resource-contact relation in the Resource Type PC_Desktops. To implement the Resource Action, perform the following steps.
Write the Resource Execution Script:
// this script creates a new ticket for the resource from which the activity is executed, i.e., creates new ticket and links it to resource
// resource - ticket relation must be configured beforehand!
import com.consol.cmas.common.model.ticket.Ticket
import com.consol.cmas.common.model.customfield.Unit
import com.consol.cmas.common.model.resource.*
import com.consol.cmas.common.service.resource.*
import com.consol.cmas.common.model.ticket.Queue
import com.consol.cmas.common.model.resource.meta.*
import com.consol.cmas.core.server.service.action.*
println 'CreateTicketForResource.groovy started ...'
Ticket newtic = new Ticket()
Queue qu = queueService.getByName("ServiceDesk")
newtic.setQueue(qu)
def subj = resource.get("PC_Desktop_Fields_basic.name")
// newtic.setSubject("New Ticket for Resource: " + resource.getId())
newtic.setSubject("New Ticket for Resource: " + subj)
newtic.set("helpdesk_standard.priority","low")
// use main contact person of the resource as main contact for the ticket
Unit maincont = new Unit()
def crit = new ResourceRelationWithTargetUnitCriteria()
crit.setResource(resource)
List<ResourceRelationWithTargetUnit> cont_list = resourceRelationService.getByCriteria(crit)
if (cont_list.size() == 0) {
workflowApi.addValidationError("ERRROR","No contact set!")
} else {
def cont_rel = cont_list[0]
maincont = cont_rel.getTargetUnit()
}
ticketService.createWithUnit(newtic,maincont)
println 'New Ticket created for resource with ID' + resource.getId()
// link ticket to resource
def resRelationDefCriteria = new ResourceRelationDefinitionCriteria()
resRelationDefCriteria.addDefinitionName("PC_Desktop_to_Ticket_Relation")
def s_res_type = resource.getResourceType()
resRelationDefCriteria.addSourceResourceType(s_res_type)
resRelationDefCriteria.addTargetQueue(qu)
log.info "resRelationDefCriteria = " + resRelationDefCriteria
log.info "resRelationDefCriteria.definitionName = " + resRelationDefCriteria.getDefinitionsNames()
def resRelationDef = resourceRelationDefinitionService.getByCriteriaUniqueResult(resRelationDefCriteria)
def resRelation = new ResourceTicketRelation(resRelationDef, resource, newtic)
log.info "resRelation" + resRelation
resourceRelationService.create(resRelation)
// go to new ticket
return actionScriptResultFactory.getPostAction(PostActionType.GOTO_TICKET, newtic)
Code example 85: Resource Execution Script for PC_Desktops to create a new Service Desk ticket for responsible PC contact
Create a Resource Action based on the script:
Figure 560: ConSol CM Admin Tool - Creating a new Resource Action
Assign the action to the correct Resource Type:
Figure 561: ConSol CM Admin Tool - Assign the Resource Action to the correct resource type
Check the functionality using the Web Client:
Figure 562: ConSol CM Web Client - Resource page with the Resource Action
Figure 563: ConSol CM Web Client - New Service Desk ticket created by the Resource Action
Figure 564: ConSol CM Web Client - Resource page with one or more ticket relations (new Service Desk ticket)
The Action Framework offers the possibility to open an ACF (Activity Control Form) when a ticket is created. The ACF is used to gather data for the following workflow activity, i.e., the ticket can be created and moved through the first workflow step very easily. The following example demonstrates this functionality. A maintenance ticket should be created for a resource (an HP printer). During the (sub-) process, an ACF should be offered to ask for data which will then be used during the next workflow activity.
To implement the Resource Action, perform the following steps.
Write the Resource Execution Script:
// this script creates a new ticket for the resource from which the activity is executed, i.e., creates new ticket and links it to resource
// resource - ticket relation must be configured beforehand!
// CreateTicketForHP_PrinterWithACF.groovy
import com.consol.cmas.common.model.ticket.Ticket
import com.consol.cmas.common.model.customfield.Unit
import com.consol.cmas.common.model.resource.*
import com.consol.cmas.common.service.resource.*
import com.consol.cmas.common.model.ticket.Queue
import com.consol.cmas.common.model.resource.meta.*
import com.consol.cmas.core.server.service.action.*
import com.consol.cmas.common.service.*
println 'CreateTicketForHP_PrinterWithACF.groovy started ...'
Ticket newtic = new Ticket()
Queue qu = queueService.getByName("SpecialTasks")
newtic.setQueue(qu)
newtic.setSubject("New Ticket for HP Printer: " + resource.getId())
newtic.set("SpecialTasks_Fields.SpecialTasksPrio","normal")
// use main contact person of the resource as main contact for the ticket
Unit maincont = new Unit()
def crit = new ResourceRelationWithTargetUnitCriteria()
crit.setResource(resource)
List<ResourceRelationWithTargetUnit> cont_list = resourceRelationService.getByCriteria(crit)
if (cont_list.size() == 0) {
log.info("ERRROR in script CreateTicketForHP_PrinterWithACF -- No contact set!")
} else {
def cont_rel = cont_list[0]
maincont = cont_rel.getTargetUnit()
}
ticketService.createWithUnit(newtic,maincont)
println 'New Ticket created for resource with ID' + resource.getId()
// link ticket to resource
def resRelationDefCriteria = new ResourceRelationDefinitionCriteria()
resRelationDefCriteria.addDefinitionName("HP_Printer_ToTicket_Relation")
def s_res_type = resource.getResourceType()
resRelationDefCriteria.addSourceResourceType(s_res_type)
resRelationDefCriteria.addTargetQueue(qu)
log.info "resRelationDefCriteria = " + resRelationDefCriteria
log.info "resRelationDefCriteria.definitionName = " + resRelationDefCriteria.getDefinitionsNames()
def resRelationDef = resourceRelationDefinitionService.getByCriteriaUniqueResult(resRelationDefCriteria)
def resRelation = new ResourceTicketRelation(resRelationDef, resource, newtic)
log.info "resRelation" + resRelation
resourceRelationService.create(resRelation)
// go to new ticket, but fill ACF before
def executionContext = activityFormDefinitionService.getExecutionContext(newtic, "defaultScope/TaskInProgress/Aufgabe_annehmen")
if (!executionContext) {
return actionScriptResultFactory.getPostAction(PostActionType.FAILURE, "action.fail.wrong.activity")
}
// Modify entities from the execution context - not the original ones
// - since the user may still press cancel.
executionContext.ticket.add("SpecialTasks_Fields","Deadline", new Date());
return actionScriptResultFactory.getPostAction(PostActionType.GOTO_TICKET, newtic, executionContext);
Code example 86: Resource Execution Script which opens a ticket and uses an ACF
Create a Resource Action based on the script.
Figure 565: ConSol CM Admin Tool - Create the Resource Action for the HP Printer maintenance ticket
Assign the action to the correct Resource Type:
Figure 566: ConSol CM Admin Tool - Assigning the Resource Action to the correct resource type (HP Printer)
Check the functionality using the Web Client:
Figure 567: ConSol CM Web Client - Resource Action for HP Printer
Figure 568: ConSol CM Web Client - New maintenance ticket for resource (HP Printer), ACF
Starting with CM version 6.10.5.4, it is possible to monitor the changes which have been performed during a resource update action. (The same applies to unit Update actions, explained in section Working with the Changes Object in Customer Update Actions).
To find out which changes have been performed use the object of class ResourceChanges in resource actions.
Please remember, the Update script will be executed:
There are two methods of the ResourceChanges object which provide information about the changed data:
Since the method return parameters contain rather complex components, we recommend to read the API doc of the ResourceChanges class. The following code provides an example for a script where a resourceChanges object is used.
/**
* Available script variables:
* Manual action:
* resource - Resource for which action is executed
*
* Create, Delete Action:
* resource - Resource for which action is executed
*
* Update Action:
* resource - Resource for which action is executed
* changes - ResourceChanges object containing information about changes done for resource entity
*
* Relation action:
* resource - Resource for which action is executed (resource-resource)
* relation - Relation object
* resourceExternalId - External resource id (resource, unit, ticket - ext resource)
*/
// Update Action Script displayPC_DesktpChangesInLog.groovy for resources in PC_Desktops
import com.consol.cmas.common.model.content.unit.UnitCommentEntry
import com.consol.cmas.common.model.content.unit.UnitAttachmentEntry
log.info 'Resource (PC_Desktop) data have been UPDATEd!'
// Are there any changes?
if (changes) {
log.info 'Yes, changes have been made to unit'
log.info 'Changes object is a ' + changes.class
}
// Have Custom Fields been changed? If yes - which?
if (changes.customFieldChangeInfo) {
log.info 'Yes, changes have been made to Custom Fields (Resource Fields)'
log.info changes.customFieldChangeInfo
log.info changes.customFieldChangeInfo.each { k, v ->
log.info "Changed field: ${k.groupName}/ ${k.fieldName}"
log.info "New value: ${v.value.value}"
log.info "Old value: ${v.previousValue.value}"
}
} else {
log.info 'No changes to Custom Fields'
}
// Have comments or attachmenst been changed? If yes - which?
log.info changes.contentChangeInfo
if (changes.contentChangeInfo){
log.info 'Yes, changes have been made in detail section'
if (changes.contentChangeInfo.value){
log.info changes?.contentChangeInfo.each { ctEntry ->
if (ctEntry?.value[0] instanceof UnitCommentEntry){
log.info 'A comment has been added.'
log.info 'Old value: ' + ctEntry?.previousValue
log.info 'New value: ' + ctEntry.value[0]?.text
log.info 'Made by the engineer ' + ctEntry.value[0]?.engineer?.name
log.info 'Creation date of the comment: ' + ctEntry.value[0]?.creationDate
} else if (ctEntry?.value[0] instanceof UnitAttachmentEntry){
log.info 'An attachment has been added.'
log.info 'Old value: ' + ctEntry?.previousValue
log.info 'New value text: ' + ctEntry.value[0]?.text
log.info 'New value file name: ' + ctEntry.value[0]?.filename
}
}
} else {
log.info 'Entry has been deleted.'
}
}
Code example 87: Resource Update script where changes are monitored and printed out to server.log
When for a resource of type PC_Desktops, the content of the two Resource Fields modell and name are modified, the following text is printed into the server.log file.
PC_DesktpChangesInLog.groovy] [Susan-] Resource (PDC_Desktop) data have been UPDATEd!
PC_DesktpChangesInLog.groovy] [Susan-] Yes, changes have been made to unit
PC_DesktpChangesInLog.groovy] [Susan-] Changes object is a class com.consol.cmas.common.model.resource.history.ResourceChanges
PC_DesktpChangesInLog.groovy] [Susan-] Yes, changes have been made to Custom Fields (Resource Fields)
PC_DesktpChangesInLog.groovy] [Susan-] {(modell,PC_Desktop_Fields_basic)=Modification{value=AbstractField{key=(modell,PC_Desktop_Fields_basic), value=Computer-0815-01}, previousValue=AbstractField{key=(modell,PC_Desktop_Fields_basic), value=Computer-0815}}, (name,PC_Desktop_Fields_basic)=Modification{value=AbstractField{key=(name,PC_Desktop_Fields_basic), value=My cool PC11}, previousValue=AbstractField{key=(name,PC_Desktop_Fields_basic), value=My cool PC}}}
PC_DesktpChangesInLog.groovy] [Susan-] Changed field: PC_Desktop_Fields_basic/ modell
PC_DesktpChangesInLog.groovy] [Susan-] New value: Computer-0815-01
PC_DesktpChangesInLog.groovy] [Susan-] Old value: Computer-0815
PC_DesktpChangesInLog.groovy] [Susan-] Changed field: PC_Desktop_Fields_basic/ name
PC_DesktpChangesInLog.groovy] [Susan-] New value: My cool PC11
PC_DesktpChangesInLog.groovy] [Susan-] Old value: My cool PC