EnergyStar Portfolio Manager - Java Client to consume their REST API with Authentication

368 views Asked by At

I am a straight up newbie. After 2 weeks of research, I've arrived at this point, still very lost and desperate.

My goal: Retrieve data from EnergyStar Portfolio Manager Restful web services / API and put that data into a SQL database or an excel worksheet.

Progress so far: 1) I found an example code that seems like it would fit what I need well, except for the authentication part. I am more successful at getting WSDL services to work than RESTful services. Particularly for EnergySTAR, requiring some kind of authentication, which I can't seem to get around to.

2) The retrieve GET protocol: http://portfoliomanager.energystar.gov/webservices/home/test/api/reporting/designMetrics/get

My source code:

package com;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
 
import com.User;
 
@Path("/wstest/property/")
public class UserManagementModule
{
    @GET
    @Path("/{propertyId}/design/metrics?measurementSystem=METRIC")
    @Produces("application/xml")
    public Response getUserById(@PathParam("propertyId") Integer id)
    
    {
        User user = new User();
        user.setId(id);
        return Response.status(200).entity(user).build();
    }
    
 
    
}
package com;
 
import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "propertyMetrics")
public class User implements Serializable {
 
    private static final long serialVersionUID = 1L;
      
    @XmlAttribute(name = "propertyId")
    private int propertyId;
    
    @XmlElement(name="metric")
    private double metric;
    
    @XmlAttribute(name = "designEnergyCost")
    private double designEnergyCost;
       
    @XmlAttribute(name = "designScore")
    private double designScore; 
    
    @XmlAttribute(name = "designSiteTotal")
    private double designSiteTotal;
    
    @XmlAttribute(name = "designSiteIntensity")
    private double designSiteIntensity;
    
    @XmlAttribute(name = "designTargetEnergyCost")
    private double designTargetEnergyCost;
    
    @XmlAttribute(name = "designTargetTotalGHGEmissions")
    private double designTargetTotalGHGEmissions;
    
    @XmlAttribute(name = "designTargetSiteTotal")
    private double designTargetSiteTotal;
 
    @XmlAttribute(name = "designTargetSiteIntensity")
    private double designTargetSiteIntensity;
    
    @XmlAttribute(name = "designTargetSourceTotal")
    private double designTargetSourceTotal;
    
    @XmlAttribute(name = "designTargetSourceIntensity")
    private double designTargetSourceIntensity;
    
    @XmlAttribute(name = "medianEnergyCost")
    private double medianEnergyCost;
    
    @XmlAttribute(name = "medianTotalGHGEmissions")
    private double medianTotalGHGEmissions;
    
    @XmlAttribute(name = "medianScore")
    private double medianScore;
     
    public int getId() {
        return propertyId;
    }
    public void setId(int propertyId) {
        this.propertyId = propertyId;
    }
  
public double getmendianScore() {
return medianScore;
}
//    
//    public void setFirstName(String firstName) {
//        this.firstName = firstName;
//    }
//    public String getLastName() {
//        return lastName;
//    }
//    public void setLastName(String lastName) {
//        this.lastName = lastName;
//    }
}
package tests;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.User; 

public class RestClientXML {

 public static void main(String[] args) 
    {
        try
        {
            URL url = new URL(" https://portfoliomanager.energystar.gov/wstest/");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Accept", "application/xml");
 
            if (conn.getResponseCode() != 200) 
            {
                throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
            }
 
            BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
            String apiOutput = br.readLine();
            System.out.println(apiOutput);
            conn.disconnect();
 
            JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            User user = (User) jaxbUnmarshaller.unmarshal(new StringReader(apiOutput));
 
            System.out.println(user.getId());
            
/*            System.out.println(user.getFirstName());
            System.out.println(user.getLastName());
             */
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

I'm know there is some authentication that needs username and pw,so I also tried this piece instead of the RestClient class, but neither works.

public static void main(String[] args) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        CloseableHttpResponse response = null;

        try {

            httpClient = HttpClients.createDefault();
            httpPost = new HttpPost("https://portfoliomanager.energystar.gov/wstest/");

            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("content-type", "application/xml"));

             StringEntity input = new StringEntity("{\"username\": \"yungv1\",\"password\": \"dummypassword\"}");
             input.setContentType("application/xml");
             httpPost.setEntity(input);

            for (NameValuePair h : nvps)
            {
                httpPost.addHeader(h.getName(), h.getValue());
            }

            response = httpClient.execute(httpPost);

            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatusLine().getStatusCode());
            }

            BufferedReader br = new BufferedReader(new InputStreamReader(
                    (response.getEntity().getContent())));

            String output;
            System.out.println("Output from Server .... \n");
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }
            
        } catch (MalformedURLException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } finally {
            try{
                response.close();
                httpClient.close();
            }catch(Exception ex) {
                ex.printStackTrace();
            }
        }

I know it's very sloppy. Can you please point the direction on how I can achieve my goal?

I also tried to run this, and keep getting the 401 errors, which I imagined the authentication fails. I don't know how else to trouble shoot this part and whether there's more thing I need to look into.

1

There are 1 answers

0
jn1kk On BEST ANSWER
conn.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String((getWebServicesUsername() + ":" + getWebServicesPassword()).getBytes()));

Where conn is HttpURLConnection.