Saturday, August 15, 2015

Call Restful Certificate secured service through BPEL - Java Embedding - upload a file to a Reset Portal.

Hi,

In this post, let us see how can we use just Java through Java embedding to call a secured Restful service through SOA Suite - BPEL. Calling the restful service through Bpel whose input and output parameters are tricky has always been a confusion to developers. Though, through OSB it is easy achievable in 11g stack of Product.

So lets see, how can we achieve it through BPEL- Java Embedding.

So BPEL works on variables and we need to get the data from the variables and pass it to the java calling service, take the response into some BPEL variables as output. Thats it.

So here I would take an example of uploading File data to the certificate secured Restful portal.

For that , I need the file name, file path, the file data, the username and password of the service to be called and most importantly the Rest API URI ie the service to be called.

String fileName = ((XMLElement) getVariableData("inputVariable","payload","/client:process/client:fileName")).getFirstChild().getNodeValue();                            
       String filePath = ((XMLElement) getVariableData("inputVariable","payload","/client:process/client:filePath")).getFirstChild().getNodeValue();                                                       
       String userName = getVariableData("userName").toString();                   
       String password = getVariableData("password").toString();                   
       String fileString = filePath+"/"+fileName;  

/* audit trail is use to print the information in the Bpel Instance Audit Trail */                         

       addAuditTrailEntry("File path is " + filePath);                               
       addAuditTrailEntry("File Name is" + fileName);                               
       addAuditTrailEntry("File String is" + fileString);               
     
        String url =  ((XMLElement) getVariableData("inputVariable","payload","/client:process/client:url")).getFirstChild().getNodeValue();    
        
         DataUpload upload = new DataUpload();                  
                           
        ServerReply reply = upload.processFileUpload(url,fileString,userName,password);                  
                                       
        addAuditTrailEntry("---:SERVER REPLIED:---");                  
        addAuditTrailEntry("Staus: "+reply.getStatus());                   
        addAuditTrailEntry("Response content --");                   
    
  
        String output = reply.getReplyContent();
        addAuditTrailEntry("Sever output: "+output);                  
        setVariableData("Result",new Integer(reply.getStatus()));             
        setVariableData("outputVariable","payload","/client:processResponse/client:respMsg",output);                
                         
}                
                
 catch(Exception ex)                                
{                                 
            StringWriter sw = new StringWriter();                     
            PrintWriter pw = new PrintWriter(sw);                     
            ex.printStackTrace(pw);                     
            String errMsg= sw.toString();                     
            String error = ex.toString();                     
            addAuditTrailEntry("Error is :" +errMsg);                        
            setVariableData("outputVariable","payload","/client:processResponse/client:respMsg",error);                    
}
       

So, in the above, Java embedded code, the getVariableData() function helps in getting the data from variables and it has a particular syntax to get the data from a variable. Similar is the case for the setVariableData() function. As you can see in the piece of code that a ServerReply class has been used to take the response from calling HTTP rest Url while a DataUpload class is used to call the Restful URI.

Basically, HttpURLConnection class has been used here to call the Rest URI setting RequestProperty, DoInput, DoOutput, and RequestMethod to the calling object.And we get a reply by httpConnection.getOutputStream(); 
Now a lot can be done on the output object as per the requirement. Code is given below. Hope it will be useful.

Now lets see  the code for calling the Rest service ie the DataUpload Class.

import java.net.HttpURLConnection;
import java.net.Authenticator;
import java.net.URL;
import java.net.PasswordAuthentication;
import java.net.URLConnection;

import java.io.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import java.util.Properties;

 private static final String LINE_FEED = "\r\n";
    private static final String CHARSET = "UTF-8";
    private static final HashMap HTTP_STATUS_MESSAGES = new HashMap();    
    private static String boundary = "===" + System.currentTimeMillis() + "===";
    private PrintWriter servletOut = null;

    static {
        HTTP_STATUS_MESSAGES.put(100 , "Continue");
        HTTP_STATUS_MESSAGES.put(101 , "Switching Protocols");
        HTTP_STATUS_MESSAGES.put(200 , "OK");
        HTTP_STATUS_MESSAGES.put(201 , "Created");
        HTTP_STATUS_MESSAGES.put(202 , "Accepted");
        HTTP_STATUS_MESSAGES.put(203 , "Non-Authoritative Information");
        HTTP_STATUS_MESSAGES.put(204 , "No Content");
        HTTP_STATUS_MESSAGES.put(205 , "Reset Content");
        HTTP_STATUS_MESSAGES.put(206 , "Partial Content");
        HTTP_STATUS_MESSAGES.put(300 , "Multiple Choices");
        HTTP_STATUS_MESSAGES.put(301 , "Moved Permanently");
        HTTP_STATUS_MESSAGES.put(302 , "Found");
        HTTP_STATUS_MESSAGES.put(303 , "See Other");
        HTTP_STATUS_MESSAGES.put(304 , "Not Modified");
        HTTP_STATUS_MESSAGES.put(305 , "Use Proxy");
        HTTP_STATUS_MESSAGES.put(307 , "Temporary Redirect");
        HTTP_STATUS_MESSAGES.put(400 , "Bad Request");
        HTTP_STATUS_MESSAGES.put(401 , "Unauthorized");
        HTTP_STATUS_MESSAGES.put(402 , "Payment Required");
        HTTP_STATUS_MESSAGES.put(403 , "Forbidden");
        HTTP_STATUS_MESSAGES.put(404 , "Not Found");
        HTTP_STATUS_MESSAGES.put(405 , "Method Not Allowed");
        HTTP_STATUS_MESSAGES.put(406 , "Not Acceptable");
        HTTP_STATUS_MESSAGES.put(407 , "Proxy Authentication Required");
        HTTP_STATUS_MESSAGES.put(408 , "Request Timeout");
        HTTP_STATUS_MESSAGES.put(409 , "Conflict");
        HTTP_STATUS_MESSAGES.put(410 , "Gone");
        HTTP_STATUS_MESSAGES.put(411 , "Length Required");
        HTTP_STATUS_MESSAGES.put(412 , "Precondition Failed");
        HTTP_STATUS_MESSAGES.put(413 , "Request Entity Too Large");
        HTTP_STATUS_MESSAGES.put(414 , "Request-URI Too Long");
        HTTP_STATUS_MESSAGES.put(415 , "Unsupported Media Type");
        HTTP_STATUS_MESSAGES.put(416 , "Requested Range Not Satisfiable");
        HTTP_STATUS_MESSAGES.put(417 , "Expectation Failed");
        HTTP_STATUS_MESSAGES.put(500 , "Internal Server Error");
        HTTP_STATUS_MESSAGES.put(501 , "Not Implemented");
        HTTP_STATUS_MESSAGES.put(502 , "Bad Gateway");
        HTTP_STATUS_MESSAGES.put(503 , "Service Unavailable");
        HTTP_STATUS_MESSAGES.put(504 , "Gateway Timeout");
        HTTP_STATUS_MESSAGES.put(505 , "HTTP Version Not Supported");
    }

    public DataUpload() {
        super();
    }

 public DataUpload(PrintWriter servletOut) {
        this.servletOut = servletOut;

    }

/* Here is the function :  */

  public ServerReply processFileUpload(String url, String uploadFile,
                                         String User,
                                         String Pwd) throws Exception {

/* for the Rest URL, we open a connection to it using the mentioned class */

        HttpURLConnection httpConnection =
                                (HttpURLConnection) new URL(url).openConnection();

        String userPassword = User + ":" + Pwd;
      /* decoded is the password into BASE - 64 format */
        String userPasswordencoding =
            new sun.misc.BASE64Encoder().encode(userPassword.getBytes());

/* Through File class instantiation, the file data is uploaded into the targetFile object.
        File targetFile = new File(uploadFile);

        OutputStream outputStream;
        PrintWriter writer;
        BufferedWriter bufWriter;
        httpConnection.setRequestMethod("POST");
        httpConnection.setDoInput(true);
        httpConnection.setDoOutput(true);
        httpConnection.setUseCaches(false);
        httpConnection.setDefaultUseCaches(false);
        httpConnection.setRequestProperty("Content-Type",
                                          "multipart/form-data; boundary=" +
                                          boundary);
        httpConnection.setRequestProperty("Authorization",
                                          "Basic " + userPasswordencoding);

        outputStream = httpConnection.getOutputStream();
     
        writer =
                new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream,
                                                                          CHARSET)),
                                true);

        addHeaderField(writer, "User-Agent", "CodeJava");

        addFilePart(writer, outputStream, targetFile.getName(), targetFile);

        ServerReply reply = finish(writer, httpConnection);
        return reply;

    }

So let us see the other function s

 private void addFilePart(PrintWriter writer, OutputStream outputStream,
                            String fieldName,
                            File uploadFile) throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"" + fieldName +
                      "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
        writer.append("Content-Type: " +
                      URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();

        writer.append(LINE_FEED);
        writer.flush();
    }

    private void addHeaderField(PrintWriter writer, String name, String value) {
        writer.append(name + ": " + value).append(LINE_FEED);
        writer.flush();
    }

    private void addFormField(PrintWriter writer, String name, String value) {
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"" + name +
                      "\"").append(LINE_FEED);
        writer.append("Content-Type: text/plain; charset=" +
                      CHARSET).append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.append(value).append(LINE_FEED);
        writer.flush();

    }


   private ServerReply finish(PrintWriter writer,
                              HttpURLConnection httpConn) throws IOException {
        ServerReply reply = new ServerReply();

        List<String> response = new ArrayList<String>();

        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();

        // checks server's status code first
        int status = httpConn.getResponseCode();
        reply.setStatus(status);
        //System.out.println(status);
        StringBuffer resp = new StringBuffer();
        
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader =
                new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
            String line = null;
            
            while ((line = reader.readLine()) != null) {
                resp.append(line);
                response.add(line);
            }
            reply.setReplyContent(resp.toString());
            reader.close();
            httpConn.disconnect();
        } else {
            reply.setReplyContent(getErrorMessage(status));
            throw new IOException("Server returned non-OK status: " + status + " : "+getErrorMessage(status));
        }
        reply.setContent(response);
        return reply;

    }

    private String getErrorMessage(int status){
        String errMsg= (String)HTTP_STATUS_MESSAGES.get(status);
        return errMsg;


Lets see the java class for Server Reply


import java.util.List;

public class ServerReply {
    public ServerReply() {
        super();
    }
    private int status;
    private List content;
    private String replyContent;

    public void setContent(List content) {
        this.content = content;
    }

    public List getContent() {
        return content;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    public void setReplyContent(String replyContent) {
        this.replyContent = replyContent;
    }

    public String getReplyContent() {
        return replyContent;
    }
}



No comments:

Post a Comment