0

Clicking on download button fetches the PDF from SAN location.But sometimes document is not available at SAN due to XYZ reason. I need to implement a polling mechanism so that clicking on download searches for the document at SAN location after every 5 secs for 5 times and also return the iteration no. in logs when the search is successful.

package abc.documentdownload;

import abc.util.Email;

import java.io.BufferedOutputStream;
import java.io.IOException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DownloadDocServlet extends HttpServlet {
    private static final Log log = LogFactory.getLog(DownloadDocServlet.class);
    private static final String CONTENT_TYPE = "text/html; charset=windows-1252";

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException,
                                                           IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException,
                                                            IOException {
        response.setContentType(CONTENT_TYPE);
        DownloadDocDAO DownloadInstance = new DownloadDocDAO();
        String downloadType = request.getParameter("downloadType");
        String pNumber = request.getParameter("PNumber");
        BufferedOutputStream output = null;
        String strFileName = pNumber + ".pdf";
        if(downloadType != null && downloadType.equalsIgnoreCase("download")){
            try{
                byte[] content=DownloadInstance.getP(pNumber);                
                log.info("COnverting content into PDF in EmailServlet");
                System.out.println("COnverting content into PDF in EmailServlet");
                response.setContentType("application/pdf");
                response.setHeader("Content-Disposition","attachment; filename=\"" + strFileName + "\"");
                response.setHeader("Cache-Control","no-cache"); 
                response.setHeader("Cache-Control","no-store"); 
                response.setHeader("Pragma","no-cache");
                response.setDateHeader("Expires", 0);
                output = new BufferedOutputStream(response.getOutputStream());
                output.write(content);
                output.flush();                            
                output.close();                

            }
            catch (Exception ex) {
                ex.printStackTrace();
                log.error("Error in DownloadDocServlet ", ex);
                /* Using the below block to trigger the email whenever there is a error*/
                Writer result = new StringWriter();
                PrintWriter printWriter = new PrintWriter(result);
                ex.printStackTrace(printWriter);
                Email emailSend = new Email();                                  
                int strEmailConfirm = emailSend.sendEmail("Exception in DownloadDocServlet of documentdownload package for pno :"+pNumber,"<B>Please find Exception Details for the DownloadDocServlet of documentdownload package</b><br><br>"+result.toString());
                log.info("strEmailConfirm in DownloadDocServlet"+strEmailConfirm); // if value is 1 ,  mail will be trigger is successful 
            } 
        }        
    }


}
Pulkit Bhatia
  • 127
  • 1
  • 7
  • 22

3 Answers3

3

What you need is some sort of timer. Here is an example on how to use TimerTasks.

First the Timer:

Timer downloadTimer = new Timer();

It doesn't do anything until you schedule a TimerTask:

TimerTask downloadTask = new TimerTask() {
    @Override
    public void run() {
       //try to download here
    };
}

now you need to schedule the task:

downloadTimer.schedule(downloadTask,1000,5000); 

This tells your downloadTimer that you want to schedule the downloadTask to be executed the first time in 1 second (1000 milliseconds) and then every 5 seconds (5000 milliseconds).

However it would run continuously unless you stop the task once you successfully downloaded or the task was executed 5 times:

private int count;
public void run() {
   if(count++==5){
       downloadTimer.cancel();  // will stop the timer
       downloadTimer.purge();   // will remove all canceled tasks from the timer
       return;   // makes sure the task will not be executed to the end
   }
   // try to download here
   // if download successful cancel and purge as well
};

This should do the trick, but I can't say if this is the best solution for your problem.

GameDroids
  • 5,584
  • 6
  • 40
  • 59
  • Thnx @gamedroids but can u plz help explain why timer is special here. as scarywombat said above, wont a simple loop with sleep do the same. while(content!=null || counter<5) {content=policyDownloadInstance.getPolicy(policyNumber); counter++; if(content==null) { log---- } Thread.sleep(5000); } – Pulkit Bhatia Oct 26 '16 at 14:54
  • `Thread.sleep` might as well be a good choice. It depends on your situation and if the Thread you are putting to "sleep" is holding on to any resources and thus blocking them for other threads. Maybe [this post](http://stackoverflow.com/q/17826651/896249) can shed some light on it and help you decide what is best. You should also consider, if it is best to let the "caller" retry every 5 seconds or the "servlet". Just be aware that the caller might encounter a timeout when the servlet is taking too long to respond. – GameDroids Oct 26 '16 at 15:43
  • Thanks , I used sleep and it worked well.. How can i add a wait loader to my code till the thread sleeps? – Pulkit Bhatia Nov 02 '16 at 18:05
  • Since it is a servlet, your wait loader is situated somewhere else in the frontend - regardless if html or other, you should be able to display an animated gif or an endless progressbar. But you should ask a new question for that, showing some frontend code. – GameDroids Nov 02 '16 at 23:40
0

Thread sleep worked well for me

 for(int i=0;i<5;i++)
                 {
                     content=getPDAO.getPFromEb( strPN);
                      DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
                      Date dateobj = new Date();
                    if(content==null) 

                     {  
                        Thread.sleep(5000);
                        }
                    else {
                        content=getPDAO.getPFromEb( strPN);
                        break;
                    }
                 } 
Pulkit Bhatia
  • 127
  • 1
  • 7
  • 22
0

You can also accomplish this by using awaitility. Please check this link on how to use

Shravan Ramamurthy
  • 3,896
  • 5
  • 30
  • 44