Monday, July 13, 2015

Web Services connection - cookie value retrieval and resubmission

package [COMPANY NAME];

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.*;
import org.jdom2.input.SAXBuilder;

public class WebServiceHelper {

private final String USER_AGENT = "Mozilla/5.0";
private static Log log = LogFactory.getLog(WebServiceHelper.class);


/**
     * Login Form
     * @param username
     * @param password
     * @param entityId
     * @return
     */
    public LoginToken login( String username, String password, String entityId) {
   
    LoginToken token = new LoginToken();
   
try {
URL url = new URL("REST-URL");

HttpURLConnection con = (HttpURLConnection) url.openConnection();

//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

String urlParameters = "UserName=" + username + "&Password=" + password + "&EntityID=" + entityId;

// Send post request
con.setDoOutput(true);

DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();

con.connect();

// retrieves the cookie from the response header
token.setCookie(con.getHeaderField("Set-Cookie"));

SAXBuilder builder = new SAXBuilder();
Document xmlDocument;

xmlDocument = builder.build(con.getInputStream());
xmlDocument.setDocType(new DocType("xml"));
Element rss = xmlDocument.getRootElement();

// retrieves the currentUserID from the xml response
token.setGuID(rss.getChild("Data").getChildText("Message").split("\\|")[1]);


} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

return token;

}
   
   
   
    public Element callService( String urlString, String method, String urlParameters, LoginToken token ) {
   
    Element element = null;
   
try {
URL url = new URL(urlString);

HttpURLConnection con = (HttpURLConnection) url.openConnection();

//add reuqest header
con.setRequestMethod(method);
con.setRequestProperty("Cookie", token.getCookie());
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

// Send post request
con.setDoOutput(true);

// USE THIS ONLY ON POST METHODS
if ( method.toUpperCase().equals("POST")) {
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
}

con.connect();

SAXBuilder builder = new SAXBuilder();
Document xmlDocument;

int status = con.getResponseCode();
log.info("Response Code: " + status);

// MAKE SURE THE RESPONSE CODE IS VALID, AKA 200.
if ( status == 200 ) {
xmlDocument = builder.build(con.getInputStream());
xmlDocument.setDocType(new DocType("xml"));
element = xmlDocument.getRootElement();
} else if ( status == 404 ) {
log.info("404 ERROR: IF YOU'RE MAKING A GET CALL. MAKE SURE YOU'RE NOT WRITING OUTPUT");
}


} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}

return element;

}
   


public static void printOutElements(Element current, int depth) {
   printSpaces(depth);
   if ( null != current ) {
   System.out.println(current.getName() + " " + current.getValue());
   List children = current.getChildren();
   Iterator iterator = children.iterator();
   while (iterator.hasNext()) {
     Element child = (Element) iterator.next();
     printOutElements(child, depth+1);
   }
   }
 
 }

private static void printSpaces(int n) {
 
   for (int i = 0; i < n; i++) {
     System.out.print(' ');
   }
 
 }
 
   

   

}

How to POST an XML Feed file to Google GSA Server with Java

Instead of use the Google GSA python scripts or other google related java code for uploading a feed to the GSA, I decided to write my own Java XML Feed Client for Google GSA. This took some time to write. If you get a 200 response , that means the file upload succeeded. Log into your GSA admin console, go to the Feeds page, scroll down and you should see the feed under the datasource column.

Hopefully it saves someone out there some time and frustration. If you enjoyed this code and want to say thank you or discuss consulting, drop me a line , sean at computervip dot com

Note: replace any [ ] with the name of your files and url's

---------------------------





import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.security.GeneralSecurityException; import java.util.logging.Level; import javax.net.ssl.HttpsURLConnection; import org.apache.http.HttpEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.log4j.Logger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;


        private static Log log = LogFactory.getLog(FeedUploader.class);
private static final String feedFileName = "[yourxmlfile].xml";
private static final String boundary = "*****";
private static final int CONNECT_TIMEOUT = 15000;
private static final int READ_TIMEOUT = 10000;
private static final String CRLF = "\r\n";
private static final String charset = "UTF-8";
private static final String BOUNDARY = "<<";
private static final String TEXT_PLAIN = "text/plain";
private static final String TEXT_XML = "text/xml";
private String feedType = "metadata-and-url";
private String dataSource = "[your-data-source-name]";
private HttpURLConnection conn = null;
OutputStream out = null;

public void uploadFeed() {

try {
// RETRIEVE THE XML FEED FROM THE WEB-INF/FEEDS FOLDER IN THIS PROJECT
// THEN CREATE THE FILE OBJECT USING THE PATH TO THE FEED
URL resource = getClass().getResource("/");
String path = resource.getPath();
path = path.replace("classes/", "feeds/");
log.info("Path = " + path.toString());
File feedFile = new File(path.toString() + feedFileName);

// CREATE AN HTTL URL CONNECTION
URL url = new URL("http://[yourserver.com]:19900/xmlfeed");
conn = (HttpURLConnection) url.openConnection();

// SET THE POST REQUEST HEADERS
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(READ_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoOutput(true); // ALLOWS THE FILE TO HAVE AN OUTPUTSTREAM
conn.setRequestProperty("ENCTYPE", "multipart/form-data");  // THIS MEANS WE'RE UPLOADING A FILE
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); // THIS MEANS WE'RE UPLOADING A FILE

// DO THE MULTI-PART ENCODING
StringBuilder buf = new StringBuilder();
byte[] prefix;

// BUILD THE DATA PAYLOAD PREFIX
contentWrapper(buf, "datasource", TEXT_PLAIN);
buf.append(dataSource).append(CRLF);
contentWrapper(buf, "feedtype", TEXT_PLAIN);
buf.append(feedType).append(CRLF);
contentWrapper(buf, "data", TEXT_XML);
prefix = buf.toString().getBytes(charset);

// BUILD THE DATA PAYLOAD SUFFIX
byte[] suffix;
buf.setLength(0);
buf.append(CRLF).append("--").append(BOUNDARY).append("--").append(CRLF);
suffix = buf.toString().getBytes(charset);

// EVERY POST REQUEST NEEDS THE CORRECT CONTENT LENGTH
// GETS THE LENGTH OF THE PREFIX TEXT, THE LENGTH OF THE FILE AND THE LENGTH OF THE SUFFIX TEXT
// THEN TAKES THE STRING VALUE OF THEM AND SETS THE "CONTENT LENGTH" ATTRIBUTE OF THE REQUEST
long contentLength = prefix.length + feedFile.length() + suffix.length;
String strContentLength = new Long(contentLength).toString();
log.info("Content Length = " + strContentLength );
conn.setRequestProperty("Content-Length", strContentLength);

// WRITE THE FILE TO THE REQUEST OBJECT IN 3 PARTS
// FIRST IS THE PREFIX, THEN THE DATA PAYLOAD, THEN THE SUFFIX
out = conn.getOutputStream();

InputStream ios = null;
out.write(prefix);
try {
       byte[] buffer = new byte[4096];
       // FILE MUST BE CONVERTED TO FILEINPUTSTREAM IN ORDER TO GET METHODS THAT ALLOW TO READ BYTES
       ios = new FileInputStream(feedFile);
       int read = 0;      
       // ITERATE THROUGH THE XML FILE AND READ 4096 BYTES AT A TIME TO THE OUTPUTSTREAM
       while ( (read = ios.read(buffer)) != -1 ) {
           out.write(buffer, 0, read);
       }
   } finally {
    ios.close();
   }
out.write(suffix);
out.flush();

// AFTER THE FILE IS SENT - GETRESPONSECODE RETRIEVES A NUMBER INDICATING THE SERVER RESPONSE
// 200 RESPONSE IS GOOD!
// 400 RESPONSE MEANS SOMETHING IS OFF
// 411 RESPONSE MEANS THE CONTENT LENGTH IS INCORRECT
int responseCode = conn.getResponseCode();
log.info("Response Code Returned: " + responseCode);

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

/**
* EACH FORM PART NEEDS PROPER FORMATTING OR AKA CONTENT DISPOSITION
* @param builder
* @param name
* @param mimetype
*/
private void contentWrapper(StringBuilder builder, String name, String mimetype) {
builder.append("--").append(BOUNDARY).append(CRLF);
builder.append("Content-Disposition: form-data;");
builder.append(" name=\"").append(name).append("\"").append(CRLF);
builder.append("Content-Type: ").append(mimetype).append(CRLF);
builder.append(CRLF);
}