Connecting to Incoming Scripted API with Java code

samiroy
Kilo Expert
Hi SN Community,
 
Need a bit of technical help . We are trying to write a sample Java code to make an inbound scripted api call and are getting stuck. 
 
we used documentation here 
 
We set up a scripted API and tested it using SN Rest API explorer
 
image.png

 
We know the rest api call works because we get the response : 
 
image.png
 
So, using the documentation / the rest api  code sample provided, we wrote our java code. 
 

  import  java.util.* ;
  import  java.sql.Date ;



   import  java.io.IOException ;
   
  import  org.apache.http.HttpException ;
  import  org.apache.http.HttpHost ;
  import  org.apache.http.auth.AuthScope ;
  import  org.apache.http.auth.UsernamePasswordCredentials ;
  import  org.apache.http.client.CredentialsProvider ;
  import  org.apache.http.client.methods.CloseableHttpResponse ;
  import  org.apache.http.client.methods.HttpGet ;
  import  org.apache.http.impl.client.BasicCredentialsProvider ;
  import  org.apache.http.impl.client.CloseableHttpClient ;
  import  org.apache.http.impl.client.HttpClients ;
  import  org.apache.http.util.EntityUtils ;

  import org.apache.http.*;
  import org.apache.*;
  
  

public class TestingSN {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("hello world");
		

		
		String instance = "ven02444.service-now.com";
		String snuser = “validIserid";
		String snpwd = “validPwd”;
		
		
		CredentialsProvider credsProvider = new BasicCredentialsProvider();
	    credsProvider.setCredentials(
	            new AuthScope(new HttpHost(instance)),
	            new UsernamePasswordCredentials(snuser, snpwd));
	    
	    CloseableHttpClient httpclient = HttpClients.custom()
	            .setDefaultCredentialsProvider(credsProvider)
	            .build();

	    try {
	        HttpGet httpget = new HttpGet("https://ven02444.service-now.com/api/x_tracl_tracecloud/getrequirement?projectPrefix=TC&reqFullTag=BR-923");
	        httpget.setHeader("Accept", "application/json");
	        httpget.setHeader("Content-Type", "application/json");
	        
	        System.out.println("Executing request " + httpget.getRequestLine());
	        CloseableHttpResponse response2 = httpclient.execute(httpget);
	        try {
	            
	        	System.out.println("srt output is " + response2.toString());
	        	
	        	} finally {
	            response2.close();
	        }
	    } catch(Exception e){
	    	e.printStackTrace();
	    } finally {
	        //httpclient.close();
	    }
		
	}

}



















  
 
However we are getting the error 
 
 
image.png
 
Appreciate your help,
 
 


 
Best Regards,
 
Sami Roy
 
 
 
1 ACCEPTED SOLUTION

samiroy
Kilo Expert

Hi All,

 

Finally got the code working. Huge Huge thanks to Jaya Bharati Tallada @ Service Now (part of the certification team). She is totally amazing. 

 

 

If you are stuck in a similar situation, here is what you should do :

 

1. Remove all clutter from your script include. Keep it very simple, and make sure it's not doing any thing. It should just print a message acknowledging receipt. If you have to use tables, make sure your user (the one calling the api) belongs to a role that has read acls on this table. 

2. Make sure you give Execute ACL on this scripted api to a role , the calling user is a member of. 

Use the sample java code below :

 

package batchJobs.Temp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.oreilly.servlet.Base64Encoder;

    public class testSNAPI {

        // API Called: https://<instance>.service-now.com/api/now/table/incident?sysparm_limit=1

        public static void main(String[] args) {

            try {

                URL url = new URL(
                        "https://ven022233334.service-now.com/api/x_tracl_tracecloud/getrequirement?projectPrefix=TC&reqFullTag=BR-923");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json");
                conn.setRequestProperty("Content-Type", "application/json");
                //String encoding = Base64Encoder.encode ("abel.tuter:abel.tuter");
                
                String userCredentials = "snUsaerId:snPassword";
                String basicAuth = "Basic " + new String(Base64Encoder.encode(userCredentials.getBytes()));

                conn.setRequestProperty("Authorization",
                		basicAuth);
                

                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(
                        (conn.getInputStream())));

                String output;
                System.out.println("Output from Server .... \n");
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }

                conn.disconnect();

            } catch (MalformedURLException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

 

 

Good Luck

 

Sami

View solution in original post

8 REPLIES 8

Ankur Bawiskar
Tera Patron
Tera Patron

Hi Roy,

So what error you are getting when you consume the ServiceNow endpoint from java?

Any exception thrown?

Regards

Ankur

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Hi Ankur,

 

Here is my code 

 

package batchJobs.Temp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.oreilly.servlet.Base64Encoder;

    public class testSNAPI {

        // API Called: https://<instance>.service-now.com/api/now/table/incident?sysparm_limit=1

        public static void main(String[] args) {

            try {

                URL url = new URL(
                        "https://ven02634.service-now.com/api/x_tracl_tracecloud/getrequirement?projectPrefix=TC&reqFullTag=BR-923");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json");
                conn.setRequestProperty("Content-Type", "application/json");
                String encoding = Base64Encoder.encode ("test:test");
                
                conn.setRequestProperty("Authorization",
                        encoding);

                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(
                        (conn.getInputStream())));

                String output;
                System.out.println("Output from Server .... \n");
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }

                conn.disconnect();

            } catch (MalformedURLException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

 

Exception in thread "main" java.lang.RuntimeException: Failed : HTTP error code : 401
at batchJobs.Temp.testSNAPI.main(testSNAPI.java:31)

 

I gave this end point the permission to execute to a role (x_tracl_traceclouduser), and made sure that this user has that role.

 

find_real_file.png

Hi Roy,

error 401 means authentication error i.e. either username or password in incorrect.

give proper username and password and check once.

Mark Correct if this solves your issue and also mark Helpful if you find my response worthy based on the impact.
Thanks
Ankur

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

samiroy
Kilo Expert

Hi Ankur and SN Community,

 

I got it to a point, where the call is happening, so there is nothing wrong with Java code. The problem is with ACL. 

 

For example, when I turn off the check box for the 'Scripted Rest Resource  / Security Tab / Requires Authentication checkbox', my code is working fine. (See attachment). 

 

It doesn't work when I turn that on. I get the 401 error with that box turned on. So my Java code is fine , but my ACLs are messed up.

 

To fix the ACL issue, I confirmed a few things:

 

1. There is an ACL for this scripted rest api , with execute permission given to a role : x_tracl_tracecloud_user

2. I made sure that the user calling the rest api, has that same role. 

 

What else do I need to do ?

 

Best

 

Sami