Want to save update set xml exported as an attachment

rahulyamgar
Tera Guru

Hello friends,

I have been using the "Export to XML" UI action on update set and now for some experimentational purpose I would like to save the XML to any of the ServiceNow record as an attachment. I had a look at the UI action "Export to XML" and found that there is a redirectURL. I tried to mimic the same using the REST GET Method and saving the output as an attachment to any of the record. But getting an 401 Unauthorized Error.

 
var current=new GlideRecord("sys_update_set");
current.get("f35cf0c507130110e835ff808c1ed07b");
var updateSetExport = new UpdateSetExport();

        var sysid = updateSetExport.exportUpdateSet(current);
		var url= "https://devxxx.service-now.com/export_update_set.do?sysparm_sys_id="+sysid+"&sysparm_delete_when_done=true&sysparm_ck=31ceffc107301110e835ff808c1ed0c566ce23842b976f8790d7ebde2f04d824dcdf0afe"
        var request = new sn_ws.RESTMessageV2();
        request.setEndpoint(url);
        request.setHttpMethod('GET');
        var user = gs.getProperty("CommitUser");
        var password = gs.getProperty("CommitUserPassword");
        request.setBasicAuth(user, password);
        request.setRequestHeader("Accept", "application/json");
        var updatesetid = request.saveResponseBodyAsAttachment(current.getTableName(), current.sys_id, current.getValue('name') + ".xml");
        var response = request.execute();
        var httpStatus = response.getStatusCode();
		
Above is returning 401 status code. Tried same in Postman but no help.
 
Could you please guide.
 
Thanks,
Rahul
8 REPLIES 8

-O-
Kilo Patron
Kilo Patron

Here's my take on a similar problem:

var RemoteUSAttacher = Class.create();

RemoteUSAttacher.prototype = Object.extendsObject(global.ExportWithRelatedLists, {

	'attacheUS': function (uniqueValue) {
		var outputStream = new Packages.java.io.ByteArrayOutputStream();

		this.hd = this.beginExport(outputStream);

		var gr = new GlideRecord(this.parent_table);

		if (gr.get(this.sys_id)) {
			this.exportRecord(gr);
			this.exportChildren();
			this._exportQuerySets();

			return this.endExport(outputStream);
		}
	},

	'endExport': function (outputStream) {
		this.hd.endElement('', '', 'unload');
		this.hd.endDocument();

		outputStream.close();

		return outputStream.toString();
	},

	'type': 'RemoteUSAttacher',

});

(function () {

	var current = new GlideRecord('ticket');

	current.newRecord();

	current.short_description = 'Retrieved Update Set Export';

	var currentUniqueValue = current.insert();

	if (current.get(currentUniqueValue)) {
		var ga = new GlideSysAttachment(),
			sys_remote_update_set_list = new GlideRecord('sys_remote_update_set');

		if (sys_remote_update_set_list.get('<remote/retrieved update set sys_id>')) {
			var exporter = new RemoteUSAttacher(sys_remote_update_set_list.getRecordClassName(), sys_remote_update_set_list.getUniqueValue()),
				fileName = normalizeName(sys_remote_update_set_list.name) + '_' + sys_remote_update_set_list.getRecordClassName() + '_' + sys_remote_update_set_list.getUniqueValue();

			exporter.addRelatedList('sys_update_xml', 'remote_update_set');

			gs.debug(fileName + '\t' + ga.write(current, fileName, 'text/xml', exporter.attacheUS()));
		}
	}

	function normalizeName (name) {
		return String(name).replace(/[^A-Za-z0-9]+/g, '-');
	}

})();

The code extends the Script Include that exports remote/retrieved update sets and makes it "attachment friendly".

The IEFE uses this new class to generate the remote/retrieved update set xml, creates a new record in table ticket and attaches the remote/retrieved update set to the new ticket. Of course you need to provide a remote/retrieved update set sys_id in place of <remote/retrieved update set sys_id> or you need to modify the code to select the remote/retrieved update sets to be attached - in case you want to attach multiple  remote/retrieved update sets. Of course you can also use a different table or existing records to which the remote/retrieved update set(s) will be attached.

All in all the remote/retrieved update set is returned by method "attacheUS" - not the best name, I admit - of class RemoteUSAttacher.

Thanks for your response!

 

But i was just trying to do the simple approach of using the REST messages. Above seems to be working but bit complex. Will explore further.

 

Thanks,
Rahul

Sorry, but how can REST be simpler? In this scenario REST is like getting from the kitchen into the diner through the neighbor's apartment, vs. directly. REST is basically a client-server messaging system. That said doing it via REST is totally possible, but you will still need too do all the stuff presented above, cause there is no OOB REST method that would provide an importable remote update set (as far as I know). So doing it via REST is actually more complicate and more resource intensive. The only instance where doing it via REST would make more sense is if the update set would be fetched by some party, but you said you want it attached to some record so it is not the case.

michaelward
Tera Guru

I am facing the same issue, but with using the 'Export to XML' on a simple update set.  I am getting a 401 Unauthorized on that export_update_set.do call, as seen in the my browser's javascript console.  The screen just goes blank.  This is an update set I created, and it is simply a global property change, just to test this.  I am a sys admin on this instance, and I created this update set.  This is after cloning this instance from another instance.  Any ideas?  We have a ticket opened with ServiceNow, so I'll post back if we get a solution.