Clarity

 View Only
  • 1.  Integrating Clarity with Service Now

    Posted Jul 14, 2020 11:08 AM
    Hello,

    I was wondering if someone integrated Clarity with ServiceNow in the past.

    This is what I want to configure:

    1. Have Clarity make an API call to update ServiceNow when a project changes to open or from open to closed.
    2. Have ServiceNow make the appropriate API Calls into Clarity on a schedule. I know how to do this on the ServiceNow side, but I'm not sure what the API Calls would be for Clarity. Again, I need to determine all the currently open projects.
    3. If neither of the above work, can Clarity send an email to a specific email address each time the state of a project changes? (open, closed.. whatever other states there may be?)
    Thanks!


  • 2.  RE: Integrating Clarity with Service Now
    Best Answer

    Posted Jul 14, 2020 11:56 AM
    Edited by Christopher Hackett Jul 17, 2020 03:46 PM
    I don't know anything about ServiceNow but from a Clarity point-of-view;

    1. You could do this with a Clarity process that contained a step which was a GEL script. The GEL script can do "almost anything" - for example calling an external API

    2. Inbound API calls to Clarity are XOG-based (being replaced by REST interfaces in the latest versions). You can make XOG calls over SOAP from "anything" that can handle calling SOAP

    Also over XOG, we can use the Query-API to execute "any" sort of NSQL-query on Clarity data (for example "list all open projects") and then pull those results (via SOAP) out to anything that that cal call SOAP.

    3. (1) and (2) work, but you could have another Clarity process that just sends an email on various project status changes (GEL script can handle sending the email).


    Ref documentation here

    Processes ; https://techdocs.broadcom.com/content/broadcom/techdocs/us/en/ca-enterprise-software/business-management/clarity-project-and-portfolio-management-ppm-on-premise/15-8-1/administration/configure-processes.html

    XOG ; https://techdocs.broadcom.com/content/broadcom/techdocs/us/en/ca-enterprise-software/business-management/clarity-project-and-portfolio-management-ppm-on-premise/15-8-1/reference/xml-open-gateway-xog-development.html


  • 3.  RE: Integrating Clarity with Service Now

    Posted Jul 18, 2020 07:07 PM
    Here is an example.  I think this worked with Istanbul or Jakarta using the direct table SOAP API.  Setting up  a scripted SOAP API is probable better that using the direct table API.

    Here is an example of getting data from ServiceNow.

    <?xml version="1.0" encoding="utf-8"?>
    <gel:script
    	xmlns:core="jelly:core"
    	xmlns:file="jelly:com.niku.union.gel.FileTagLibrary"
    	xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    	xmlns:nikuq="http://www.niku.com/xog/Query"
    	xmlns:soap="jelly:com.niku.union.gel.SOAPTagLibrary"
    	xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    	xmlns:sql="jelly:sql"
    	xmlns:util="jelly:util"
    	xmlns:x="jelly:org.apache.commons.jelly.tags.xml.XMLTagLibrary"
    	xmlns:xog="http://www.niku.com/xog"
    	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    
    	<gel:log>Start this Script</gel:log>
    	
    	<!-- Set the endpoint to ServiceNow and set our Authorization for Basic -->
    	<core:set var="soapEndPoint" value="https://servicenowdev.service-now.com/sys_user_list.do?SOAP" />
    	<core:invokeStatic var="base64" className="com.niku.union.utility.Base64" method="encode">
    		<core:arg type="java.lang.String" value="admin:password" />
    	</core:invokeStatic>
    	<core:set var="basicAuth" value="Basic ${base64}" />
    	<gel:log>basicAuth = ${basicAuth}</gel:log>
    
    	<!-- Open a connection to ServiceNow and set our request headers -->
    	<core:new var="soapUrl" className="java.net.URL">
    		<core:arg type="java.lang.String" value="${soapEndPoint}" />
    	</core:new>
    	<core:invoke var="connection" on="${soapUrl}" method="openConnection"/>
    	<core:expr value="${connection.setDoOutput(true)}" />
    	<core:expr value='${connection.setRequestMethod("POST")}'/>
    	<core:expr value='${connection.setRequestProperty("Content-type", "text/xml; charset=utf-8")}'/>
    	<core:expr value='${connection.setRequestProperty("SOAPAction", soapEndPoint)}'/>
    	<core:expr value='${connection.setRequestProperty("Authorization", basicAuth)}'/>
    	<core:set var="requestXml">
    		<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    			<soapenv:Header>
    				<Action soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.service-now.com/sys_user/getRecords</Action>
    			</soapenv:Header>
    			<soapenv:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    				<getRecords xmlns="http://www.service-now.com/sys_user">
    					<last_name xmlns="">greiff</last_name>
    			</getRecords>
    			</soapenv:Body>
    		</soapenv:Envelope>
    	</core:set>
    	
    	<!-- Write out our getRecords request to ServiceNow -->
    		
    	<core:invoke var="outputStream" on="${connection}" method="getOutputStream" />
    	<core:new var="outputStreamWriter" className="java.io.OutputStreamWriter">
    		<core:arg type="java.io.OutputStream" value="${outputStream}" />
    	</core:new>	
    	<core:expr value="${outputStreamWriter.write(requestXml)}" />
    	<core:expr value="${outputStreamWriter.close()}" />
    	
    	<!-- Read in the response from ServiceNow into a org.w3c.dom.Document -->
    	<core:invoke var="inputStream" on="${connection}" method="getInputStream" />
    	
    	<!--
    	<gel:parse var="wellFormed" file="${inputStream}" />
    	<gel:serialize fileName="wellFormed.xml" var="${wellFormed}"/>
    	-->	
    	<core:new var="inputStreamReader" className="java.io.InputStreamReader">
    			<core:arg type="java.io.InputStream" value="${inputStream}" />
    	</core:new>
    
    	<core:new var="stringBuilder" className="java.lang.StringBuilder" />
    	<core:set var="data" value="${inputStreamReader.read()}" />
    	<core:while test="${data != -1}">
    	<core:invokeStatic var="char" className="java.lang.Character" method="toChars" >
    		<core:arg type="int" value="${data}" />
    	</core:invokeStatic>
    	<core:invokeStatic var="charString" className="java.lang.String" method="valueOf" >
    		<core:arg value="${char}" />
    	</core:invokeStatic>
    		<core:set var="char" value="${java.lang.String.valueOf(java.lang.Character.toChars(data))}"/>
    			<core:invoke method="append" on="${stringBuilder}">
    				<core:arg value="${charString}" />
    			</core:invoke>
    			<core:set var="data" value="${inputStreamReader.read()}" />
    	</core:while>
    
    	<core:set var='soapEnvIndex' value='${stringBuilder.toString().indexOf("SOAP-ENV")}' />
    	<gel:log>This is the index for soapEnvIndex = ${soapEnvIndex}</gel:log>
    	<gel:log>${stringBuilder.toString().substring(soapEnvIndex-1)}</gel:log>
    	
    	<!--
    	<x:parse var="soapEnv" escapeText="false" text="${stringBuilder.toString().substring(soapEnvIndex-1)}" />
    	
    	<core:file name="xmlFragment.xml" escapeText="false" omitXmlDeclaration="true" outputMode="xml">
    			<core:expr escapeText="false" value="${soapEnv.getRootElement().asXML()}"/>
    	</core:file>
    	
    	<gel:parse var="wellFormed" file="xmlFragment.xml"/>	
    
    	<gel:parse var="wellFormed">
         <core:expr escapeText="false" value="${soapEnv.getRootElement().asXML()}"/>
    	</gel:parse>
    	-->
    
    	<gel:log>End this Script</gel:log>
    	
    </gel:script>

    For ServiceNow to write into PPM, you are going to need to use the Object API.  To read use the Query API -- Have your PPM team built you an NSQL which provide the data you are looking for from PPM to ServiceNow and that query will be available in the Query API.

    https://cppm-dev.ondemand.ca.com/niku/wsdl/Object?tenantId=clarity
    https://cppm-dev.ondemand.ca.com/niku/wsdl/Query?tenantId=clarity


    V/r,
    Gene