Yesterday I saw a question on the SAS® Communities site from Nick about Registering Custom Tasks and managing the capability metadata that’s used for role based access control on those custom tasks. I found Nick’s question especially interesting because we have some free Metacoda Custom Tasks and those techniques can also be used to control access to them.
Nick had mentioned how he used SAS® Enterprise Guide® to register the capability metadata for some custom tasks, was asking about doing the same for the SAS Add-In for Microsoft Office, and also about how one would go about removing the capability metadata. Chris Hemedinger later replied with a response that I found very useful. There was a link to one of his prior blog posts on the topic (Controlling access to custom tasks in SAS Enterprise Guide – The SAS Dummy) and some information on using RegAddin.exe to get the capability metadata populated for use by the Add-In. Chris also mentioned there was not a way to remove the custom task capability metadata short of the potentially dangerous technique of using the SAS Open Metadata Interface’s DeleteMetadata facility.
Having already registered the custom task metadata myself, I now needed a way to remove it so I could repeat the process for future documentation and testing purposes. I used the DeleteMetadata method. This is the main topic for this blog post and it serves 2 purposes: the first is that I wanted to document how I did it so I could do it again later; the second is that it was an opportunity for me to use the SAS Management Console XML Metadata Interface and capture a few screenshots along the way. I rarely use the SAS Management Console XML Metadata Interface and it’s always a journey of re-discovery every time I do. This time I wanted a permanent memory of the steps so I could refer to them again in future. I also ran into an interesting unknown-public-type issue that initially prevented me from deleting the capability metadata, so I’ll show how I resolved that too.
“Here Be Dragons”
Any discussion of using SAS Open Metadata Interface methods for updating and deleting metadata comes with an obligatory warning. Whilst a very powerful and flexible facility, it is also potentially very dangerous and should be used with great care. Simple mistakes might result in the unintended modification or deletion of the wrong metadata objects and possibly many more objects than intended. Before working with this facility it is advisable to:
- Test carefully in a private SAS environment that nobody else relies on for their day to day work. This is often not the case for “development” environments that developers might rely on. I will sometimes create a small private throwaway environment (Lev9) just for these types of potentially destructive/disruptive activities.
- Ensure you have a recent metadata backup and perform any ad-hoc ones as necessary.
- Be confident that your metadata backups are working and usable i.e. a recent test restore was done successfully.
Finding Capability Metadata to Delete
At this point the custom tasks capability metadata has already been registered in metadata by using the SAS Enterprise Guide Task Import Wizard. I can see them in a SAS Management Console role properties dialog capabilities tab.
To delete the custom task capability metadata we need to find it using some identifying information: at least the object type and the object id. The SAS metadata model object type for capabilities is ApplicationAction. To find the object id we need to search the ApplicationAction objects in metadata using some known characteristic of the custom task. You could use the custom task name. I used the unique class id I originally generated when I added into the source code of our custom task (as shown below).
This class id will be found in the ActionIdentifier attribute of the ApplicationAction object.
Once we find an ApplicationAction object with the appropriate Name and/or ActionIdentifier we can use its unique Id attribute value to delete it.
Below are 2 of the possible ways to find the ApplicationAction object. I’ve shown point & click methods which are easy for occasional or one-off situations. If you want a regular repeatable method you’ll probably want to write code instead.
Finding Capability Metadata: Method 1
The first method, and the one I tend to use when searching for metadata, is to use our free Metacoda Metadata Explorer Plug-in. Use the Options button to narrow the search down to Model Types and a single selection of ApplicationAction.
Then search for the custom task capability (ApplicationAction) object. Our custom tasks include the word metadata in the name so that was the search term. Selecting the target capability shows the ActionIdentifier and Id attribute values (‘d280f922-0c97-4426-9038-2ff376f1ec0a’ and ‘A5PQCYE6.B8000093’). You might also notice the PublicType attribute value is “ApplicationAction” – more about that later.
Finding Capability Metadata: Method 2
One of the other methods for finding custom task capability metadata is to use the SAS Management Console XML Metadata Interface plug-in. This is also the plug-in that I’ll use to delete the metadata later. The XML Metadata Interface plug-in is one of the standard SAS Management Console plug-ins, but it’s disabled by default. If you want to enable it you need to move an omitoolsmc directory as explained in this SAS Global Forum paper or in this SAS Users Groups blog post.
After enabling the XML Metadata Interface plug-in and restarting SAS Management Console, it becomes available under the Tools menu:
The first tab, Get Metadata Objects, can be used to search for the custom task capability object. In this case I’m searching with the custom task class id so I need to:
- Select ApplicationAction in the Type combo box
- Tick the OMI_XMLSELECT (128) checkbox
- Specify the XMLSELECT filter criteria in the Options field. I’m searching for a class id in the ActionIdentifier attribute so I use:
<XMLSELECT Search="@ActionIdentifier='d280f922-0c97-4426-9038-2ff376f1ec0a'" />
- Click the Execute button to run the query.
- Look for the Id value in the Output XML field. As you can see below, in my case this is A5PQCYE6.B8000092.
Now I have the object id (A5PQCYE6.B8000092) I can move onto the Delete Metadata tab to try to delete the object.
Deleting Capability Metadata: First (Failed) Attempt
On my first attempt to delete the metadata it failed with the following error displayed in the Output XML field:
Error: com.sas.iom.SASIOMDefs.GenericError: The public type definition 'ApplicationAction' (version 1000000), specified by object ApplicationAction : 'Metadata Column Finder' (ID="A5PQCYE6.B8000092"), does not exist.
I mentioned earlier that the custom type’s ApplicationAction object, as registered by SAS Enterprise Guide, had a PublicType attribute value of “ApplicationAction”. It turns out that this public type, as specified, is not present in metadata, hence the error. If you look at the ApplicationAction objects for the standard SAS Enterprise Guide capabilities they have a blank PublicType value. It appears as though the SAS Enterprise Guide Task Import Wizard is creating ApplicationAction objects with invalid PublicType values, and that in turn is preventing them from being deleted.
In order to be able to delete the custom task capabilities I needed to update the ApplicationAction object for the custom task to change the PublicType value from “ApplicationAction” to “” (blank). This can be done with the Update Metadata tab.
Updating Capability Metadata
The Update Metadata tab can be used to modify the metadata for an existing object. If you know what you want to change, and what you want to change it to, you could just type the appropriate XML into the Input XML field. If you don’t know the name of the attribute(s), or you want to tweak the existing attribute value(s), you can use the Get Metadata tab to query the existing metadata and generate template XML to use in the Update Metadata tab.
To use the Get Metadata tab to fetch all the simple attributes for the ApplicationAction object with id A5PQCYE6.B8000092:
- Tick the OMI_ALL_SIMPLE (8) checkbox
- Use the following Input XML field value:
<ApplicationAction Id="A5PQCYE6.B8000092" />
- Click the Execute button to run the query.
- Review the Output XML field contents.
The Output XML from the Get Metadata tab can then be copied, pasted into the Input XML field on the Update Metadata tab, and then edited as required before submitting.
In the Update Metadata tab screenshot below, I edited the pasted XML to specify values only for the Id and PublicType attributes: the Id attribute because that identifies the ApplicationAction object to be updated; and the PublicType attribute because that’s the only attribute I want to change, in this case from “ApplicationAction” to “” (blank).
This was the Input XML:
<ApplicationAction Id="A5PQCYE6.B8000092" PublicType="" />
After clicking the Execute button, it updated successfully. There was no error message and the Input XML field value was echoed to the Output XML field, as shown below.
Now the custom task capability (ApplicationAction object) has a valid blank PublicType value, it can be deleted using the Delete Metadata tab.
Deleting Capability Metadata: Second (Successful) Attempt
To delete the custom task capability, use the Delete Metadata tab to specify the object type and id as an XML string in the Input XML field:
<ApplicationAction Id="A5PQCYE6.B8000092" />
Click the Execute button, and if all goes well you should see the text “Delete succeeded” in the Output XML field.
Now I have a way of successfully deleting custom task metadata, and some examples to remind me how to use the SAS Management Console XML Metadata Interface plug-in when I need it. If I find I need to do this more regularly than I expect, I can always write some code to automate it. ;)