package org.swellrt.server.box.events.gcm;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.inject.Inject;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.json.JSONException;
import org.json.JSONObject;
import org.swellrt.server.box.events.Event;
import org.swellrt.server.box.events.EventDispatcher;
import org.swellrt.server.box.events.EventDispatcherTarget;
import org.swellrt.server.box.events.EventRule;
import org.waveprotocol.wave.util.logging.Log;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
public class GCMDispatcher implements EventDispatcherTarget {
private static final Log LOG = Log.get(GCMDispatcher.class);
public final static String NAME = "gcm";
private static final String REGISTRATION_IDS = "registration_ids";
private static final String DATA = "data";
private String authKey;
private String sendUrl;
private GCMSubscriptionStore subscriptionManager;
private boolean isReady = false;
private HttpClient httpClient;
@Inject
public GCMDispatcher(GCMSubscriptionStore subscriptionManager) {
this.subscriptionManager = subscriptionManager;
initialize(System.getProperty("event-dispatch.config.file", "config/event-dispatch.config"));
}
protected void initialize(String confFilePath) {
FileReader fr;
try {
fr = new FileReader(confFilePath);
} catch (FileNotFoundException e) {
LOG.warning("GCM dispatcher configuration file not found: " + confFilePath
+ ". GCM module initialization aborted.");
return;
}
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(fr);
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonElement gcmElement = jsonObject.get(NAME);
if (gcmElement == null) {
LOG.warning("GCM dispatcher configuration error: gcm section not found in " + confFilePath
+ ". GCM module initialization aborted.");
return;
}
JsonObject gcmObject = gcmElement.getAsJsonObject();
if (!(gcmObject.has("authKey")) || !(gcmObject.has("url"))) {
LOG.warning("GCM dispatcher configuration error: config keys not found " + confFilePath
+ ". GCM module initialization aborted.");
return;
}
initialize(gcmObject.get("authKey").getAsString(), gcmObject.get("url").getAsString());
}
public void initialize(String authKey, String sendUrl) {
this.authKey = authKey;
this.sendUrl = sendUrl;
this.httpClient = new HttpClient();
LOG.warning("GCM event dispatcher succesfully configured");
isReady = true;
}
@Override
public String getName() {
return NAME;
}
@Override
public void dispatch(EventRule rule, Event event, String payload) {
if (!isReady) return;
LOG.fine("Event dispatched to GCM: " + rule + " on " + event + " with payload " + payload);
PostMethod postMethod = new PostMethod(sendUrl);
postMethod.setRequestHeader("Content-Type", "application/json");
postMethod.setRequestHeader("Authorization", "key=" + this.authKey);
try {
JSONObject dataPayload = new JSONObject(payload);
JSONObject completePayload = new JSONObject();
String waveId = event.getWaveId().serialise();
List<String> subscriptors =
subscriptionManager.getSubscriptorsDevicesExcludingUser(waveId, event.getAuthor());
if (subscriptors.isEmpty()) {
return;
}
completePayload.put(REGISTRATION_IDS, subscriptors);
completePayload.put(DATA, dataPayload);
String stringPayload = completePayload.toString();
RequestEntity requestData = new ByteArrayRequestEntity(stringPayload.getBytes(Charset.forName("UTF-8")));
postMethod.setRequestEntity(requestData);
int resultCode = httpClient.executeMethod(postMethod);
if (resultCode != HttpStatus.SC_OK) {
throw new IOException("HTTP response code " + resultCode);
}
} catch (JSONException e) {
LOG.severe("Error sending GCM request", e);
} catch (HttpException e) {
LOG.severe("Error sending GCM request", e);
} catch (IOException e) {
LOG.severe("Error sending GCM request", e);
} finally {
postMethod.releaseConnection();
}
}
}