BusinessObjects Board

Rescheduling the report using BO SDK jsp

I have the pseudo code to reschedule the failed report through UI using jsp.I dont want to waste time again coding from the beginning if someone already has.
Can someone please help me with the code if have handy? I can customize as per my requirement.
Any help is much appreciated.

Below is the algorithm I have.

  1. Retrieve the failed instances in an IInfoObjects collection
  2. Loop through the collection and get the ISchedulingInfo class for each InfoObject
  3. Call ISchedulingInfo.setType(CeScheduleType.ONCE) and ISchedulingInfo.setRightNow(true) on each failed instance. Do NOT save each object
  4. Outside the loop, call IInfoStore.schedule()

You may want to remove events to ensure the job actually kicks off as soon as a slot is open on the system


kpavan999 (BOB member since 2011-01-26)

This is part of the code that I use. It’s a Java application, but could be easily converted to JSP.

Couple of important things to note – by default, a rescheduled instance will assume the owner of the user doing the reschedule. My script sets it to the original owner. I also remove any Events that the instance is waiting for.

This is what it does:
[list=1:a3abaf5113][:a3abaf5113]Ask user for timeframe to evaluate
[
:a3abaf5113]Get failed instances during the timeframe
[:a3abaf5113]For each failed instance, check if there is a successful instance during the same time period; if found, take no action.
[
:a3abaf5113]Get a new IInfoObjects collection for the failed instance
[:a3abaf5113]Get the original owner ID, and set the scheduled owner to match
[
:a3abaf5113]Set instance to run immediately
[:a3abaf5113]Remove any Events associated with the instance
[
:a3abaf5113]Set the expiration date (one day in the future)
[:a3abaf5113]Ask if instance should be rescheduled
[
:a3abaf5113]If yes, reschedule the instance and delete the failed instance[/list]

		Integer inStart = new Integer(getInput("Start hours ago","12"));
		Integer inEnd = new Integer(getInput("End hours ago (negative for future)","0"));
		
		Calendar calStart = Calendar.getInstance();
		calStart.add(Calendar.HOUR,-inStart);  
		Calendar calEnd = Calendar.getInstance();
		calEnd.add(Calendar.HOUR,-inEnd);
		
		SimpleDateFormat sdfGMT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat sdfHere = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
		sdfGMT.setTimeZone(TimeZone.getTimeZone("GMT"));
		
		String strStart = sdfGMT.format(calStart.getTime());
		String strEnd = sdfGMT.format(calEnd.getTime());
		
		System.out.println("Looking for failed instances between " + sdfHere.format(calStart.getTime()) + " and " + sdfHere.format(calEnd.getTime()));
		
		String userInput="";

		String timeCondition = "'" + strStart + "' and '" + strEnd + "'";
		
		IInfoObjects oInfoObjects = oInfoStore.query("select top 100 * from ci_infoobjects where si_schedule_status = 3   and si_update_ts between  " + timeCondition); 

        Date exDate;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1);
        exDate = calendar.getTime();

    	outfor:

	    for(int x =0;x < oInfoObjects.size();x++)
	    {
	    	IInfoObject oI = (IInfoObject)oInfoObjects.get(x);
	    	IInfoObjects oSuccess = (IInfoObjects) oInfoStore.query("select * from ci_infoobjects where si_parentid = " + oI.getParentID() + " and si_schedule_status in (1,9,0) and si_kind = '" + oI.getKind() + "' and si_update_ts  between " + timeCondition );
	    	if(oSuccess.size() > 0)
	    		continue outfor;
	    	
	    	IInfoObjects oScheds = oInfoStore.query("select * from ci_infoobjects,ci_appobjects where si_id = " + oI.getID());
		    IInfoObject oSched = (IInfoObject) oScheds.get(0);

		    Integer iOwner = (Integer) oI.properties().getProperty("SI_OWNERID").getValue();
		    
	        oSched.getSchedulingInfo().setScheduleOnBehalfOf(iOwner);
	        oSched.getSchedulingInfo().setRightNow(true);
	        oSched.getSchedulingInfo().setType(CeScheduleType.ONCE);
	        
	        while(oSched.getSchedulingInfo().getDependencies().size() > 0)
	        	oSched.getSchedulingInfo().getDependencies().remove(0);
	        
	        oSched.getSchedulingInfo().setEndDate(exDate);
	        System.out.print("   reschedule? ");
	        userInput = scanner.nextLine();
	        
	        if(userInput.toUpperCase().equals("Y"))
	        {
	        	oInfoStore.schedule(oScheds);
	        	oI.deleteNow();
	        }
	    }
	}
	
	String getInput(String prompt,String defaultValue)
	{
		System.out.println(prompt + " (" + defaultValue + "):");
		String result = scanner.nextLine(); 
		if(result.equals(""))
		{
			System.out.println(defaultValue);
			return defaultValue;
		}
		return result;
	}

joepeters :us: (BOB member since 2002-08-29)

Hey Joepeters,

Thanks a lot. This is what exactly Im looking for.
With my limited knowledge I will try to convert into JSP.

Meantime just in case if you find the same code in JSP please do reply here, I think it will be helpful for many out here.

Thanks agiain for your prompt reply.


kpavan999 (BOB member since 2011-01-26)

Hi Joepeters,

I have somehoe managed to get the code in JSP using your logic, but unfortunately it is not working. If you dont mind, can you please see if you can find what is causing the issue?
Im neither getting the error nor able to reschedule the report.

Im completely sure about the code till try block.
Thanks a lot for your help.


<%@ page import = "com.crystaldecisions.sdk.occa.infostore.*" %>  
<%@ page import = "com.crystaldecisions.sdk.framework.CrystalEnterprise" %>  
<%@ page import = "com.crystaldecisions.sdk.exception.SDKException" %>  
<%@ page import = "com.crystaldecisions.sdk.framework.IEnterpriseSession" %>  
<%  
    // logon information  
    String boCmsName  = "*******" ;  
    String boUsername = "********" ;  
    String boPassword = "*******" ;  
    String boAuthType = "secEnterprise" ;  
          // report  
    String reportName = "23A_Fails" ;  
          // logon  
    IEnterpriseSession ceSession = CrystalEnterprise.getSessionMgr().logon( boUsername, boPassword, boCmsName, boAuthType ) ;  
    IInfoStore         oInfoStore = (IInfoStore)ceSession.getService( "", "InfoStore" ) ;  
    // get the scheduled report  
   String cr_query = "Select Top 1 * "  
                      + "From CI_INFOOBJECTS "  
                      + "Where SI_NAME='" + reportName + "' "  ;
                      //+ "and SI_INSTANCE=1 and SI_RECURRING=1 " ;  
    IInfoObjects boInfoObjects = oInfoStore.query( cr_query ) ;  
    if ( boInfoObjects.size() == 0 ) {  
       out.println( "<b>Scheduled report not found: '" + reportName + "'</b><br />" ) ;  
       ceSession.logoff() ;  
       return ;  
    }  

    try {  

         IInfoObjects oInfoObjects = oInfoStore.query("select top 1 * from ci_infoobjects where SI_NAME='" + reportName + "' " );
    		   out.println("select top 1 * from ci_infoobjects where SI_NAME='" + reportName + "' ");
          IInfoObject oI = (IInfoObject)oInfoObjects.get( 0 ); 
          IInfoObjects oSuccess = (IInfoObjects) oInfoStore.query("select * from ci_infoobjects where si_parentid = " + oI.getParentID() + " and si_schedule_status in (1,9,0) and si_kind = '" + oI.getKind() + "'  "  ); 
 //         if(oSuccess.size() > 0) 
 //            continue outfor; 
          IInfoObjects oScheds = oInfoStore.query("select * from ci_infoobjects,ci_appobjects where si_id = " + oI.getID()); 
          IInfoObject oSched = (IInfoObject) oScheds.get(0); 
          Integer iOwner = (Integer) oI.properties().getProperty("SI_OWNERID").getValue();
          oSched.getSchedulingInfo().setScheduleOnBehalfOf(iOwner); 
           oSched.getSchedulingInfo().setRightNow(true); 
           oSched.getSchedulingInfo().setType(CeScheduleType.ONCE); 
 
    } catch ( SDKException e ) {  
       out.println( "<font color=red><b>couldn't reschedule report</b></font><br />" ) ;  
       out.println( e.toString() ) ;  
    }  
    // logoff  
    ceSession.logoff() ;  
%>  

kpavan999 (BOB member since 2011-01-26)

The first thing I see is that you’re not looking for a failed instance; your query will pick up the base report, and not an instance.

The next thing I see is that you’re not calling oInfoStore.schedule(oScheds), which is what actually creates the schedule instance.


joepeters :us: (BOB member since 2002-08-29)

You are right,

  1. I’m hardcoding for a single report just to see how it works.
  2. I didn’t use “oInfoStore.schedule(oScheds)” as it wasn’t there in your code as well. But I have used in the new code below, still the report is not scheduled as per the old report scheduled instance…

What is happening here is, report is getting scheduled but it is not sending mail/attachment unlike the original schedule instance.
Below are the details of the rescheduled instance


<%@ page import = "com.crystaldecisions.sdk.occa.infostore.*" %>  
<%@ page import = "com.crystaldecisions.sdk.framework.CrystalEnterprise" %>  
<%@ page import = "com.crystaldecisions.sdk.exception.SDKException" %>  
<%@ page import = "com.crystaldecisions.sdk.framework.IEnterpriseSession" %>  
<%  
    // logon information  
    String boCmsName  = "***" ;  
    String boUsername = "***" ;  
    String boPassword = "***" ;  
    String boAuthType = "secEnterprise" ;  
          // report  
    String reportName = "SDK_TEST" ;  
          // logon  
    IEnterpriseSession ceSession = CrystalEnterprise.getSessionMgr().logon( boUsername, boPassword, boCmsName, boAuthType ) ;  
    IInfoStore         oInfoStore = (IInfoStore)ceSession.getService( "", "InfoStore" ) ;  
    IInfoObjects oInfoObjects = oInfoStore.query("select top 1 * from ci_infoobjects where SI_NAME='" + reportName + "' " );
    IInfoObject oI = (IInfoObject) oInfoObjects.get(0); 
          IInfoObject oSched = (IInfoObject) oInfoObjects.get(0); 
           oSched.getSchedulingInfo().setRightNow(true); 
           oSched.getSchedulingInfo().setType(CeScheduleType.ONCE); 
             oInfoStore.schedule(oInfoObjects); 
              
%>


Now my doubt is can we reschedule the report directly or we need to get all the scheduling info like from/to/events etc and then apply them for the new schedule? I think it will be a tedious job as it could be SMTP or FTP or inbox or anything.


kpavan999 (BOB member since 2011-01-26)

Hi Joepeters,

just wanted to know if in case you got a chance to look into my issue.
BO SDK.doc (329.0 KB)


kpavan999 (BOB member since 2011-01-26)

I just got back from vacation.

Yes, but you are hardcoding for the base report, not the instance. So your code is creating a new schedule from the base; it is not rescheduling an existing instance.

Yes, it’s there: oInfoStore.schedule(oScheds);

This is expected as you are scheduling the base report. Your initial CMS query needs to be more specific – you are currently querying on si_name; you either need to use si_parentid instead or add si_recurring=1.

Joe


joepeters :us: (BOB member since 2002-08-29)

Thanks a lot joepeters,
Now I got the confidence that this code will work.

It is now taking the properties like, report format/emailing info etc.
The only problem is -> it is going to pending status though we are setting it to runNow and the old recurring instance doesnt have any events to wait for or to trigger.


<%@ page import = "com.crystaldecisions.sdk.occa.infostore.*" %> 
<%@ page import = "com.crystaldecisions.sdk.framework.CrystalEnterprise" %> 
<%@ page import = "com.crystaldecisions.sdk.exception.SDKException" %> 
<%@ page import = "com.crystaldecisions.sdk.framework.IEnterpriseSession" %> 
<% 
    // logon information 
    String boCmsName  = "***" ;  
    String boUsername = "***" ;  
    String boPassword = "***" ;  
    String boAuthType = "secEnterprise" ;  
    // report  
    String reportName = "SDK_TEST" ;  
          // logon 
    IEnterpriseSession ceSession = CrystalEnterprise.getSessionMgr().logon( boUsername, boPassword, boCmsName, boAuthType ) ; 
    IInfoStore         oInfoStore = (IInfoStore)ceSession.getService( "", "InfoStore" ) ; 
   // IInfoObject oI = (IInfoObject) oScheds.get(0);
    IInfoObjects oScheds = oInfoStore.query("select top 1 * from ci_infoobjects where   si_recurring=1 and SI_NAME='"+reportName+"'" );
    
          IInfoObject oSched = (IInfoObject) oScheds.get(0);
           oSched.getSchedulingInfo().setRightNow(true);
           oSched.getSchedulingInfo().setType(CeScheduleType.ONCE);
          
 while(oSched.getSchedulingInfo().getDependencies().size() > 0) 
               oSched.getSchedulingInfo().getDependencies().remove(0);
          
   oInfoStore.schedule(oScheds);
             
%>

Can you please tell me if there is still anything needed to make it run as expected.


kpavan999 (BOB member since 2011-01-26)

The code looks ok. Is the report set to use a specific job server?

If you go into CMC, select the instance that’s generated by this script, and reschedule it (still in CMC), does it work?


joepeters :us: (BOB member since 2002-08-29)

It is now resolved, posting the solution for the benefit of others…

I just changed the order of below 2 commands


           oSched.getSchedulingInfo().setRightNow(true); 
           oSched.getSchedulingInfo().setType(CeScheduleType.ONCE); 

as


           oSched.getSchedulingInfo().setType(CeScheduleType.ONCE); 
           oSched.getSchedulingInfo().setRightNow(true); 

Thank you Joepeters for your help so far.


kpavan999 (BOB member since 2011-01-26)

Hello All,

i am using the above thread for developing a script to re-run a failed job in BOE BI . am creating a vb script . i got stuck with how to write the below JSp code to VBs . Please help with key words to achieve the below 3 steps in VBS.

    IInfoObject oSched = (IInfoObject) oScheds.get(0); 
       oSched.getSchedulingInfo().setRightNow(true); 
       oSched.getSchedulingInfo().setType(CeScheduleType.ONCE);

satheesh_rvs (BOB member since 2019-05-02)

Dim oSched as IInfoObject 
oSched = oScheds(1)
oSched.SchedulingInfo.RightNow = True
oSched.SchedulingInfo.Type = ceScheduleTypeOnce

joepeters :us: (BOB member since 2002-08-29)

Hello Joe,

Thank a lot for your timely help . Since am new to this topic , could you please validate the below VBS script which will help me to push it confidently in server . Also let me know whether SDK needed for running this VB script .



strComputerName = CreateObject("WScript.Network").ComputerName

On Error Resume Next

Set SessionManager = CreateObject("CrystalEnterprise.SessionMgr")
    Set esession = SessionManager.Logon("USERNAME", "PASSWORD", strComputerName, "secEnterprise")
    Set oInfoStore = esession.Service("", "InfoStore")
  set oScheds = oInfoStore.Query("select top 1 * from ci_infoobjects where   si_recurring=1 and SI_NAME='"TESTJOB"'"")
 
oSched = oScheds(1)
oSched.SchedulingInfo.RightNow = True
oSched.SchedulingInfo.Type = ceScheduleTypeOnce

while(oSched.SchedulingInfo.Dependencies.size > 0)
               oSched.SchedulingInfo.Dependencies.remove(0)
wend
         
   oInfoStore.schedule(oScheds)

SessionManager.logoff

WScript.Quit

satheesh_rvs (BOB member since 2019-05-02)

@joepeters
Can some one please help me for completing this sscript .


satheesh_rvs (BOB member since 2019-05-02)

I’ve done SDK programming in Java and VBA but not VBS, so I can’t be certain it will work.

But this line:

  set oScheds = oInfoStore.Query("select top 1 * from ci_infoobjects where   si_recurring=1 and SI_NAME='"TESTJOB"'"") 

doesn’t look right. Is it actually a report named “TESTJOB”? If so, it should be:

  set oScheds = oInfoStore.Query("select top 1 * from ci_infoobjects where   si_recurring=1 and SI_NAME='TESTJOB' ") 

joepeters :us: (BOB member since 2002-08-29)

Hi joepeters,

I made the query works . But the core help needed is here in the below lines .
am running the script without any SDK .

oSched = oScheds(1) 
oSched.SchedulingInfo.RightNow = True 
oSched.SchedulingInfo.Type = ceScheduleTypeOnce 

while(oSched.SchedulingInfo.Dependencies.size > 0) 
               oSched.SchedulingInfo.Dependencies.remove(0) 
wend 
          
   oInfoStore.schedule(oScheds) 

Also if you have the Java script for this , please help me by providing the code . Since i need to run the Code as script (standalone ) to reschedule the failed job .


satheesh_rvs (BOB member since 2019-05-02)

What is the exact problem you’re having with that code?


joepeters :us: (BOB member since 2002-08-29)

Hello Joe,

Sorry for delay in replying .

The problem is that it launches a process like “Wscript” kind of a instance and it running with high CPU . Also fore each command line execution its creating a process and CPU is getting completely utilized .

Once the reschedule is done . process should get killed automatically right ?

Note: am trying to rerun only one scheduled report Job .


satheesh_rvs (BOB member since 2019-05-02)

If it’s hanging and pegging the CPU then maybe your While loop is never completing?


joepeters :us: (BOB member since 2002-08-29)