Skip to content

Instantly share code, notes, and snippets.

@shunjikonishi
Last active December 21, 2015 02:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shunjikonishi/6238250 to your computer and use it in GitHub Desktop.
Save shunjikonishi/6238250 to your computer and use it in GitHub Desktop.
The prototype of HerokuApi wrapper for Playframework 1.2.x
package models;
import play.libs.WS;
import play.libs.WS.HttpResponse;
import play.libs.WS.WSRequest;
import com.google.gson.Gson;
import java.io.IOException;
import java.io.Serializable;
public class HerokuApi implements Serializable {
private static final long serialVersionUID = 3163402804252788807L;
public static final String HOST_ID = "https://id.heroku.com";
public static final String HOST_API = "https://api.heroku.com";
public enum Scope {
Global("global"),
Identity("identity"),
Read("read"),
Write("write"),
ReadProtected("read-protected"),
WriteProtected("write-protected")
;
private String value;
private Scope(String value) {
this.value = value;
}
public String toString() { return this.value;}
}
public static String getOAuthUrl(String clientId, Scope... scope) {
StringBuilder buf = new StringBuilder();
for (Scope s : scope) {
if (buf.length() > 0) {
buf.append("%20");
}
buf.append(s);
}
return HOST_ID + "/oauth/authorize?client_id=" + clientId + "&response_type=code&scope=" + buf.toString();
}
public static HerokuApi authenticate(String secret, String code) throws IOException {
HttpResponse res = WS.url(HOST_ID + "/oauth/token")
.setParameter("grant_type", "authorization_code")
.setParameter("code", code)
.setParameter("client_secret", secret)
.post();
if (res.getStatus() == 200) {
return fromJson(res.getString());
} else {
throw new IOException("Heroku login failed: " + res.getString());
}
}
public static HerokuApi fromJson(String json) {
return new Gson().fromJson(json, HerokuApi.class);
}
private String access_token;
private int expires_in;
private String refresh_token;
private String token_type;
private String session_nonce;
private boolean debug = false;
private int rateLimitRemaining = -1;
private long requestStart;
private Gson gson = new Gson();
private Account account = null;
private HerokuApi() {
}
public boolean isDebug() { return this.debug;}
public void setDebug(boolean b) { this.debug = b;}
public int getRateLimitRemaining() { return this.rateLimitRemaining;}
private void debugLog(String name, String value) {
if (this.debug) {
long t = System.currentTimeMillis() - this.requestStart;
System.out.println("HerokuApi - " + name + "(" + t + "ms): " + value);
}
}
public String getAuthorization() {
return this.token_type + " " + this.access_token;
}
public String toString() {
return getAuthorization();
}
private WSRequest buildRequest(String path) {
this.requestStart = System.currentTimeMillis();
return WS.url(HOST_API + path)
.setHeader("Accept", "application/vnd.heroku+json; version=3")
.setHeader("Authorization", getAuthorization());
}
private <T> T handleResponse(String name, HttpResponse res, Class<T> returnClass) throws IOException {
String body = res.getString();
int status = res.getStatus();
debugLog(name, body);
String rlr = res.getHeader("RateLimit-Remaining");
if (rlr != null) {
try {
this.rateLimitRemaining = Integer.parseInt(rlr);
} catch (NumberFormatException e) {
//not occur
e.printStackTrace();
}
}
if (status >= 200 && status < 300) {
return gson.fromJson(body, returnClass);
} else {
if (body.indexOf("\"id\"") != -1 && body.indexOf("\"message\"") != -1) {
HerokuApiError e = gson.fromJson(body, HerokuApiError.class);
throw new HerokuApiException(status, e);
} else {
throw new IOException("status=" + status + ", body=" + body);
}
}
}
public Account getAccount() throws IOException {
if (this.account != null) {
return this.account;
}
HttpResponse res = buildRequest("/account").get();
this.account = handleResponse("getAccount", res, Account.class);
return this.account;
}
public int getRateLimits() throws IOException {
HttpResponse res = buildRequest("/account/rate-limits").get();
return handleResponse("getRateLimits", res, RateLimits.class).getRemaining();
}
public static class HerokuApiError {
private String id;
private String message;
public String getId() { return this.id;}
public String getMessage() { return this.message;}
}
public static class HerokuApiException extends IOException {
private int status;
private String id;
public HerokuApiException(int status, HerokuApiError e) {
super(e.getMessage());
this.status = status;
this.id = id;
}
public int getStatus() { return this.status;}
public String getId() { return this.id;}
}
public static class Account {
private boolean allow_tracking;
private boolean beta;
private String created_at;
private String email;
private String id;
private String last_login;
private String updated_at;
private boolean verified;
public boolean allowTracking() { return this.allow_tracking;}
public boolean isBeta() { return this.beta;}
public String getEmail() { return this.email;}
public String getId() { return this.id;}
public boolean isVerified() { return this.verified;}
}
public static class RateLimits {
private int remaining;
public int getRemaining() { return this.remaining;}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment