Introduction
This blog focuses on how to get documents out from the SAP Print Queue and how to pass them on to an external Output Management System (OMS) for processing and printing using the SAP provided API. It supplements the already existing blog with example implementation with JAVA code of SAP_COM_0466 - Print Queue Item - Read (A2X).
Example code for SAP_COM_0466 - Print Queue Item - Read (A2X)
See the details on SAP_COM_0466 | SAP Help Portal how to configure your SAP S/4HANA Cloud Public Edition system to support Print Queues.
Prerequisites:
Please note that code is meant as example how the api can be used. Code is not claimed to be complete, to be error free or to be state of the art programming style.
Usage of the example code
Remind!
Code is meant as example how the api can be used. Code is not claimed to be complete, to be error free or to be state of the art programming style. Nevertheless feedback is welcome.
import java.net.CookieManager;
import java.net.http.*;
import java.net.URI;
import java.util.Base64;
import java.util.concurrent.*;
import org.json.*;
class SAP_COM_0466_example {
public static int Get_System_Details( System_Str[] System_Details ) throws Exception {
// get details of the SAP sytem for api and other calls
// pre-defined system details and credentials for testing, needs to be configured in SAP system beforehand
System_Details[0] = new System_Str (
"https://my######-api.s4hana.ondemand.com", // URL to SAP system DEF
"SAPUSERNAME", // SAP User Name / Client ID on BTP
"########################################", // SAP User Password / Client Secret on BTP
"SAP S/4HANA CLOUD (Public Edition)", // SAP System Type
"dummy", // Sub-Account name, only required for BTP
10); // intervall for ICM cache polling
/*
System_Details[0] = new System_Str (
"https://abc.private.corp", // URL to SAP system ABC
"SAPUSERNAME", // SAP User Name / Client ID on BTP
"########################################", // SAP User Password / Client Secret on BTP
"SAP S/4HANA CLOUD (Private Edition)", // SAP System Type
"dummy", // Sub-Account name, only required for BTP
10); // intervall for ICM cache polling
*/
/*
System_Details[0] = new System_Str (
"https://api.eu11.print.services.sap/qm", // URL to SAP system BTP
"#############################################################", // SAP User Name / Client ID on BTP
"#################################################################################", // SAP User Password / Client Secret on BTP
"SAP BTP", // SAP System Type
"icc-btp-test-abcd1234"); // Sub-Account name, only required for BTP
10); // intervall for ICM cache polling
*/
return (200); // return good status code
}
public static int Get_Bearer_Token( StringBuilder BearerToken, String Credentials, System_Str System_Details ) throws Exception {
// For BTP only to get the bearer token for oauth authentication
String UrlLocator; // http request url
HttpRequest RequestBody; // http request body
HttpHeaders RequestHeaders; // http request header
HttpResponse ResponseReply; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String BearerTokenL; // BTP bearer token for oauth authentication
UrlLocator = System_Details.SystemUrl.substring(System_Details.SystemUrl.indexOf("api.") + 4); // extract location of BTP account
UrlLocator = UrlLocator.substring(0,UrlLocator.indexOf("."));
UrlLocator = "https://" + System_Details.SubDomain + ".authentication." + UrlLocator + ".hana.ondemand.com"; // build url for bearer token request
//System.out.println(UrlLocator + "/oauth/token?grant_type=client_credentials");
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create( UrlLocator + "/oauth/token?grant_type=client_credentials")) // add path for bearer token request
.version(HttpClient.Version.HTTP_2) // set call context
.header("Content-Type", "application/x-www-form-urlencoded")
.header("accept", "application/xml")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_Bearer_Token");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
//System.out.println("BearerToken: \"" + BearerTokenL + "\"");
//System.out.println("");
BearerTokenL = ResponseReply.body().toString(); // extract bearer token from http reply
if ( BearerTokenL.contains("\"access_token\":\"") ) // check if bearer token is in http reply
{
BearerTokenL = BearerTokenL.substring(BearerTokenL.indexOf("\"access_token\":\"")+16); // extract bearer token
BearerTokenL = BearerTokenL.substring(0,BearerTokenL.indexOf("\","));
}
else {
BearerTokenL = "";
System.out.println(" BearerToken missing in http-reply"); // show error message if bearer token is missing
}
BearerToken.setLength(0); // return the bearer token
BearerToken.append(BearerTokenL);
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int Get_IcmCache( StringBuilder ICMcache, String Credentials , System_Str System_Details) throws Exception {
// see SAP doumenation for the API
HttpRequest RequestBody; // http request body
HttpHeaders RequestHeaders; // http request header
HttpResponse ResponseReply; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String ICMCacheL; // SAP ICM cache status
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/Get_IcmCache")) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_IcmCache");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
ICMCacheL = ""; // extract the SAP ICM cache status from http reply
if ( ResponseReply.body().toString().length() > 99 ) { // check if SAP ICM cache status is in http reply
if ( !ResponseReply.body().toString().contains("{\"d\":{") ) { // check if proper structure is received
System.out.println("error occured"); // exit in case of elemd "d" does not exist
System.out.println(ResponseReply.body());
System.exit(0);
}
JSONObject jObject = new JSONObject(ResponseReply.body().toString()); // read the json structure
ICMCacheL = jObject.getJSONObject("d").getString("content"); // extract the SAP ICM cache status
}
ICMcache.setLength(0); // return the SAP ICM cache status
ICMcache.append(ICMCacheL);
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int Get_PrintQueuesOfUserExt( int[] Qname_No, String[] ListOfQueues, String Credentials, System_Str System_Details ) throws Exception {
// see SAP doumenation for the API
HttpRequest RequestBody; // http request body
HttpHeaders RequestHeaders; // http request header
HttpResponse ResponseReply; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
int Qname_NoL; // Number of Print Queues
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/Get_PrintQueuesOfUserExt")) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_PrintQueuesOfUserExt");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
Qname_NoL = 0; // initiate the number of Print Queues
if ( ResponseCodeL.equals("200") && (ResponseReply.body().toString().length() > 99) ) { // check if there is payload
if ( !ResponseReply.body().toString().contains("{\"d\":{") ) { // check if proper structure is received
System.out.println("error occured"); // exit in case of elemd "d" does not exist
System.out.println(ResponseReply.body());
System.exit(0);
}
JSONObject jObject = new JSONObject(ResponseReply.body().toString()); // read the json structure
JSONArray Qresults = jObject.getJSONObject("d").getJSONArray("results");
for (int i = 0; i < Qresults.length(); i++) {
ListOfQueues[i] = Qresults.getJSONObject(i).getString("Qname"); // read the Print Queue name
//System.out.println(ListOfQueues[i]);
Qname_NoL = i + 1; // adjust number of Print Queues
if ( Qname_NoL > 100 ) {
System.out.println("Support max. 100 print queues"); // inform on limitation
break; // stop after 100 Print Queues
}
}
}
Qname_No[0] = Qname_NoL; // return the number of Print Queues
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int Get_NumberOfQItemsExt( int[] NrOfNewItems, String Qname, String Credentials, System_Str System_Details ) throws Exception {
// see SAP doumenation for the API
HttpRequest RequestBody; // http request body
HttpResponse ResponseReply; // http request header
HttpHeaders RequestHeaders; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String paramset; // parameter set for api call
int NrOfNewItemsL; // number of new print queue items
paramset = "?Qname='" + Qname + "'"; // build the parameter set - set print queue name
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/Get_NumberOfQItemsExt" + paramset)) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_NumberOfQItemsExt");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
//System.out.println("NrOfNewItems: " + NrOfNewItemsL);
//System.out.println("");
NrOfNewItemsL = 0; // initiate the number of print queue items
if ( ResponseReply.body().toString().length() > 99 ) { // check if there is payload
if ( !ResponseReply.body().toString().contains("{\"d\":{") ) { // check if proper structure is received
System.out.println("error occured"); // exit in case of elemd "d" does not exist
System.out.println(ResponseReply.body());
System.exit(0);
}
JSONObject jObject = new JSONObject(ResponseReply.body().toString()); // read the json structure
NrOfNewItemsL = jObject.getJSONObject("d").getInt("NrOfNewItems"); // read from json structure number of print queue items
}
NrOfNewItems[0] = NrOfNewItemsL; // return the number of print queue items
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int Get_Next_QItemsExt( QItem_Str[] QItemList, int NumberOfItems, String Qname, String Credentials, System_Str System_Details ) throws Exception {
// see SAP doumenation for the API
HttpClient client; // http handle
HttpRequest RequestBody; // http request body
HttpResponse ResponseReply; // http request header
HttpHeaders RequestHeaders; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String QItemDoc; // queue item docuement raw data
String QItemId; // queue item ID
String QItemFile; // queue item file name
String QItemBlob; // queue item blob
long QItemSize; // queue item file size
String paramset; // parameter set for api call
paramset = "?NumberOfItems=" + NumberOfItems ; // build the parameter set - set number of queue items
paramset = paramset + "&Qname='" + Qname + "'"; // set print queue name
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/Get_Next_QItemsExt" + paramset)) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("x-csrf-token", "fetch")
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_Next_QItemsExt");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
if ( ResponseReply.body().toString().length() > 99 ) { // check if there is payload
if ( !ResponseReply.body().toString().contains("{\"d\":{") ) { // check if proper structure is received
System.out.println("error occured"); // exit in case of elemd "d" does not exist
System.out.println(ResponseReply.body());
System.exit(0);
}
JSONObject jObject = new JSONObject(ResponseReply.body().toString()); // read the json structure
JSONArray jQItemList = jObject.getJSONObject("d").getJSONArray("results"); // read from json the results structure
//System.out.println("jQItemList.length: " + jQItemList.length());
for (int i = 0; i < jQItemList.length(); i++) { // loop on the print queue items
JSONObject jQItem = jQItemList.getJSONObject(i); // read from json the print queue item
QItemDoc = jQItem.getString("Documents"); // read from json the Documents structure
JSONArray jDocuments = new JSONArray(QItemDoc); // read the nested json structure
//System.out.println(jDocuments);
for (int j = 0; j < jDocuments.length(); j++) {
JSONObject jDocumentItem = jDocuments.getJSONObject(j); // read from json the documents for the print queue item
QItemId = jQItem.getString("QItemId"); // read from json the print queue item ID
QItemFile = jDocumentItem.getString("document_name"); // read from json the print queue item file name
QItemBlob = jDocumentItem.getString("blob"); // read from json extract from the blob
QItemBlob = QItemBlob.substring(0,3) + "..." + QItemBlob.substring(QItemBlob.length()-3,QItemBlob.length());
QItemSize = jDocumentItem.getLong("filesize"); // read from json the print queue item file size
//System.out.println("-Documents: " + QItemDoc);
//System.out.println("- QItemId: " + QItemId);
//System.out.println("- QItemFile: " + QItemFile);
//System.out.println("- QItemSize: " + QItemBlob);
//System.out.println("- QItemBlob: " + QItemSize);
//System.out.println("");
QItemList[i] = new QItem_Str(QItemId, QItemFile, QItemBlob, QItemSize, "", 0); // return print queue meta data
if (j > 0) break; // ignore attachemens for now ####
}
}
}
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int PrintItemStatusSet( QItem_Str[] QItemList, int NoOfQItems_Queues, String Qname, String Credentials, System_Str System_Details ) throws Exception {
// see SAP doumenation for the API
HttpClient client; // http handle
HttpRequest RequestBody; // http request body
HttpHeaders RequestHeaders; // http request header
HttpResponse ResponseReply; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String jsonInputString; // JSON structure for PrintItemStatusSet
String XCsrfToken; // XCsrfToken for api call
String Getcookie; // session cookie for api call
// Part 0: Create client for common part
client = HttpClient.newBuilder() // Preprare to set cookie context
.cookieHandler(new CookieManager())
.version(HttpClient.Version.HTTP_2)
.build();
// Part 1: query for x-csrf-token
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/PrintItemStatusSet")) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("x-csrf-token", "fetch")
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("HEAD", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = client.send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("PrintItemStatusSet");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("ResponseBody");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
XCsrfToken = ResponseHeaders.firstValue("X-CSRF-Token").toString(); // extract required X-CSRF-Token
XCsrfToken = XCsrfToken.replace("Optional[", "").replace("]", "");
//System.out.println("X-CSRF-Token: \"" + XCsrfToken + "\"");
Getcookie = ResponseHeaders.toString(); // get session cookie
Getcookie = Getcookie.substring(Getcookie.indexOf("set-cookie=[")+12);
Getcookie = Getcookie.substring(0,Getcookie.indexOf("]"));
//System.out.println("Cookie: \"" + Getcookie + "\"");
jsonInputString = "{\"Qname\":\"" + Qname + "\",\"ItemsStatus\":\"["; // build the json string for api call
for (int i = 0; i < NoOfQItems_Queues; i++) {
jsonInputString = jsonInputString + "{\\\"ITEM_ID\\\":\\\"";
jsonInputString = jsonInputString + QItemList[i].QItemId; // add the Print Queue Item ID
jsonInputString = jsonInputString + "\\\",\\\"STATUS\\\":\\\"S\\\","; // set success code
jsonInputString = jsonInputString + "\\\"STATUS_DESC\\\":\\\"Printed by NN\\\"}"; // set success message
if ( i < ( NoOfQItems_Queues - 1 )) {
jsonInputString = jsonInputString + ",";
}
}
jsonInputString = jsonInputString + "]\"}"; // close the json structure
// Part 2: post print item status
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/PrintItemStatusSet")) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("X-CSRF-Token", XCsrfToken) // add XCsrfToken
.header("cookie", Getcookie) // add session cookie
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("POST", HttpRequest.BodyPublishers.ofString(jsonInputString))
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = client.send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("PrintItemStatusSet POST");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("HttpResponseReply");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
XCsrfToken = ResponseHeaders.firstValue("X-CSRF-Token").toString(); // extract required X-CSRF-Token
XCsrfToken = XCsrfToken.replace("Optional[", "").replace("]", "");
//System.out.println("X-CSRF-Token: \"" + XCsrfToken + "\"");
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public static int Set_QItems_LastErrorExt( int NumberOfItems, String Qname, String Credentials, System_Str System_Details ) throws Exception {
// see SAP doumenation for the API
HttpRequest RequestBody; // http request body
HttpResponse ResponseReply; // http request header
HttpHeaders RequestHeaders; // http reply body
HttpHeaders ResponseHeaders; // http reply header
String ResponseCodeL; // http response code
String paramset; // parameter set for api call
paramset = "?Qname='" + Qname + "'"; // build the parameter set - set the print queue name
paramset = paramset + "&NumberOfItems=" + NumberOfItems; // set the number of print queue items
paramset = paramset + "&ResetToStatus='F'"; // set the status failure
paramset = paramset + "&ResetToStatusDesc='test_for_Set_QItems_LastErrorExt'"; // set the status message
RequestBody = HttpRequest.newBuilder() // build the http request
.uri(URI.create(System_Details.SystemUrl + "/sap/opu/odata/SAP/API_CLOUD_PRINT_PULL_SRV/Set_QItems_LastErrorExt" + paramset )) // add path for function
.version(HttpClient.Version.HTTP_2) // set call context
.header("x-csrf-token", "fetch")
.header("Content-Type", "application/json")
.header("accept", "application/json")
.header("user-agent", "printqueuequery")
.header("Authorization", Credentials)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
RequestHeaders = RequestBody.headers(); // read the request header for error analysis
ResponseReply = HttpClient.newHttpClient().send(RequestBody, HttpResponse.BodyHandlers.ofString()); // initiate http call
ResponseHeaders = ResponseReply.headers(); // read the reply header for error analysis
ResponseCodeL = ResponseReply.toString();
ResponseCodeL = ResponseCodeL.substring(ResponseCodeL.length()-3,ResponseCodeL.length()); // extract http status code
//System.out.println("");
//System.out.println("Get_Next_QItemsExt");
//System.out.println("");
//System.out.println("HttpRequest");
//System.out.println(RequestBody);
//System.out.println("");
//System.out.println("RequestHeaders");
//System.out.println(RequestHeaders);
//System.out.println("");
//System.out.println("ResponseReply");
//System.out.println(ResponseReply);
//System.out.println("");
//System.out.println("HttpResponseReply");
//System.out.println(ResponseReply.body());
//System.out.println("");
//System.out.println("ResponseHeaders");
//System.out.println(ResponseHeaders);
//System.out.println("");
return (Integer.valueOf(ResponseCodeL)); // return the http status code
}
public record QItem_Att ( // structure for single queue item
String QItemFile, // queue item file name
String QItemBlob, // queue item blob
long QItemSize // queue item file size
) {}
public record QItem_Str ( // structure for single queue item
String QItemId, // queue item ID
String QItemFile, // queue item file name
String QItemBlob, // queue item blob
long QItemSize, // queue item file size
String QItemUName, // user who created the request
int NoOfAtt // number of attachements
) {}
public record System_Str ( // structure for system detail + access data
String SystemUrl, // URL to SAP system
String SystemUser, // SAP User Name / Client ID on BTP
String SystemPassword, // SAP User Password / Client Secret on BTP
String SystemType, // SAP System Type
String SubDomain, // Sub-Account name, only required for BTP
int Interval // intervall for ICM cache polling
) {}
// main program
public static void main(String[] args) throws Exception {
String Get_IcmCache_old; // ICM cache status of prior call
String Get_IcmCache_new; // ICM cache status of current call
StringBuilder ICMCache = new StringBuilder(""); // ICM cache status
String ApiCall; // Buffer for text for current API call
int ResponseCode; // Result code of API call
String Credentials; // Buffer for logon credential
StringBuilder BearerToken = new StringBuilder(""); // Buffer for bearer token
System_Str System_Details[] = new System_Str[1]; // System details strcture
String ListOfQueues[] = new String[100]; // List of print queues
int NumberOfQueues[] = new int[1]; // Number of print queues
int NoOfQItems_Queue[] = new int[1]; // Number of print queue items in print queue
int NoOfQItems_Queues[] = new int[100]; // Number of print queue items per print queue
QItem_Str QItemList[] = new QItem_Str[100]; // List of print queue item IDs per queue
long timer_cur; // Current time stamp
long timer_new; // time stamp for next planned ICM cache polling
int lauf1; // loop variable 1
int lauf2; // loop variable 2
boolean new_request; // flag for new print queue items
ResponseCode = Get_System_Details( System_Details ); // get system details
System.out.println(ResponseCode + " Get_System_Details");
Credentials = "Basic " + new String(Base64.getEncoder().encode((System_Details[0].SystemUser + ":" + System_Details[0].SystemPassword).getBytes())); // build credentials
ApiCall = "Get_PrintQueuesOfUserExt"; // prepare api call
ResponseCode = Get_PrintQueuesOfUserExt(NumberOfQueues, ListOfQueues, Credentials, System_Details[0]); // call api Get_PrintQueuesOfUserExt
if ( (ResponseCode == 401) & ( System_Details[0].SystemType.equals("SAP BTP")) ) { // in case of expired bearer token request new bearer token
ApiCall = "Get_Bearer_Token"; // prepare Get_Bearer_Token
ResponseCode = Get_Bearer_Token( BearerToken, Credentials, System_Details[0]); // call Get_Bearer_Token
System.out.println(ResponseCode + " " + ApiCall); // output api call result
Credentials = "Bearer " + BearerToken.toString(); // copy bearer token to credentials
//System.out.println("BearerToken: \"" + Credentials + "\"");
if (ResponseCode == 200) { // retry api call in case of good bearer token
ApiCall = "Get_PrintQueuesOfUserExt"; // prepare api call
ResponseCode = Get_PrintQueuesOfUserExt(NumberOfQueues, ListOfQueues, Credentials, System_Details[0]); // call api Get_PrintQueuesOfUserExt
}
}
System.out.println(ResponseCode + " " + ApiCall); // output api call result
if (ResponseCode != 200) // in case of invalid bearer token quit program
System.exit(0);
for (lauf1 = 0; lauf1 < NumberOfQueues[0]; lauf1++) { // output of all print queues
System.out.println(" Queue:" + ListOfQueues[lauf1]);
}
if ( System_Details[0].SystemType.equals("SAP BTP") )
Get_IcmCache_old = "SCP 1704067200000"; // on BTP: seconds since 1.1.1970 on 1.1.2024
else
Get_IcmCache_old = "19000101000000.0000000"; // on SAP S/4 HANA (any type) initial date+time
new_request = false; // set flag for new print queue items to false
Get_IcmCache_new = Get_IcmCache_old; // set flag for new print queue items to false
timer_cur = java.time.Instant.now().getEpochSecond(); // get current time stamp
timer_new = timer_cur; // make sure that next ICM cache polling take place immediately
while (true) { // loop forever
timer_cur = java.time.Instant.now().getEpochSecond(); // read current time-stamp
if (timer_cur >= timer_new) { // check if next ICM cache polling reached
timer_new = timer_cur + System_Details[0].Interval; // set time for next ICM cache polling
ApiCall = "ICMCache"; // prepare api call
ResponseCode = Get_IcmCache(ICMCache, Credentials, System_Details[0]); // call api Get_IcmCache
Get_IcmCache_new = ICMCache.toString(); // convert ICM cahce status to string
System.out.println( ResponseCode + " " + ApiCall + ": \"" + Get_IcmCache_new + "\"" ); // output api call result
if ( Get_IcmCache_new.equals(Get_IcmCache_old) == false ) { // compare old and new ICM cache status
Get_IcmCache_old = Get_IcmCache_new; // in case of ICM cache status set flag for new print queue items
new_request = true;
}
}
else {
System.out.print("\r" + (timer_new - timer_cur) + " \r"); // output countdown until next ICM cache status polling
TimeUnit.SECONDS.sleep(1); // wait for 1 second
}
if (new_request == true) { // incase of new print queue items
new_request = false; // delete flag for new print queue items
System.out.println(" ICM cache changed -> new request(s)"); // output ICM cache change
for (lauf1 = 0; lauf1 < NumberOfQueues[0]; lauf1++) { // loop on print queues
ApiCall = "NoOfQItems_Queue "; // prepare api call
ResponseCode = Get_NumberOfQItemsExt(NoOfQItems_Queue, ListOfQueues[lauf1], Credentials, System_Details[0]); // call api Get_NumberOfQItemsExt
NoOfQItems_Queues[lauf1] = NoOfQItems_Queue[0]; // copy number of print queue items in print queue
if ( NoOfQItems_Queues[lauf1] > 100 ) {
NoOfQItems_Queues[lauf1] = 100; // if number of print queue items in print queue larger then 100 reduce to 100
new_request = true; // do next queue item query on next loop
}
System.out.println(ResponseCode + " " + ApiCall + " for Queue: " + String.format("%-20s",ListOfQueues[lauf1]) + " : " + String.format("%3s",NoOfQItems_Queues[lauf1])); // output number of print queue items in print queue
if ( NoOfQItems_Queues[lauf1] > 0 ) { // check of there are queue items in print queue
ApiCall = "Get_Next_QItemsExt"; // prepare api call
ResponseCode = Get_Next_QItemsExt(QItemList, NoOfQItems_Queues[lauf1], ListOfQueues[lauf1], Credentials, System_Details[0]); // call api Get_Next_QItemsExt
System.out.println(ResponseCode + " " + ApiCall + " for Queue: " + String.format("%-20s",ListOfQueues[lauf1]) + " : " + String.format("%3s",NoOfQItems_Queues[lauf1])); // output api call result
for (lauf2 = 0; lauf2 < NoOfQItems_Queues[lauf1]; lauf2++) { // output queue items details
System.out.println(" QItemId: " + QItemList[lauf2].QItemId); // queue item ID
System.out.println(" QItemFile: " + QItemList[lauf2].QItemFile); // queue item file name
System.out.println(" QItemSize: " + QItemList[lauf2].QItemSize ); // queue item blob
System.out.println(" QItemBlob: " + QItemList[lauf2].QItemBlob ); // queue item file size
System.out.println("");
}
if (true) { // Either set transfer success "true" or set transfer failed "false"
ApiCall = "PrintItemStatusSet"; // prepare api call
ResponseCode = PrintItemStatusSet(QItemList, NoOfQItems_Queues[lauf1], ListOfQueues[lauf1], Credentials, System_Details[0]); // call api PrintItemStatusSet
System.out.println(ResponseCode + " " + ApiCall + " for Queue: " + ListOfQueues[lauf1]); // output result of api call
}
else {
ApiCall = "Set_QItems_LastErrorExt"; // prepare api call
ResponseCode = Set_QItems_LastErrorExt(NoOfQItems_Queues[lauf1], ListOfQueues[lauf1], Credentials, System_Details[0]); // call api Set_QItems_LastErrorExt
System.out.println(ResponseCode + " " + ApiCall + ": " + ListOfQueues[lauf1] + "for " + NoOfQItems_Queues[lauf1] + " items"); // output result of api call
}
} // if ( NoOfQItems_Queues
} // for (lauf1
} // if (new_request
} // while (true
} // main
} // class SAP_COM_0466_exampleRegards
Martin
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 36 | |
| 28 | |
| 27 | |
| 26 | |
| 26 | |
| 26 | |
| 25 | |
| 24 | |
| 23 | |
| 23 |