Skip to content
This repository was archived by the owner on Apr 18, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README

This file was deleted.

6 changes: 6 additions & 0 deletions examples/emm-notifications/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea
target
.DS_Store
../.DS_Store
emm-notifications.iml
.idea
4 changes: 4 additions & 0 deletions examples/emm-notifications/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Play for Work EMM Push Notification
==================================

Text goes here.
12 changes: 12 additions & 0 deletions examples/emm-notifications/google_settings.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# NOT PUBLIC
# Values for our internal developer console project (enterprise-cloud-pub-sub)
ServiceAccountEmail=368628613713-t4hf388f34tdn5lhpdcu1qqfgio01626@developer.gserviceaccount.com

# Download from here: https://pantheon.corp.google.com/project/enterprise-cloud-pub-sub/apiui/credential
ServiceAccountP12KeyFile=secret.p12
ProjectName=enterprise-cloud-pub-sub
SubscriptionName=projects/enterprise-cloud-pub-sub/subscriptions/push-subscription
TopicName=projects/enterprise-cloud-pub-sub/topics/default-topic

# Configured for the project mentioned above
PushEndpoint=e.r-k.co
110 changes: 110 additions & 0 deletions examples/emm-notifications/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.android.work.emmnotifications</groupId>
<artifactId>emm-notifications</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>emm-notifications</name>
<url>http://maven.apache.org</url>

<pluginRepositories>
<pluginRepository>
<id>protoc-plugin</id>
<url>http://sergei-ivanov.github.com/maven-protoc-plugin/repo/releases/</url>
</pluginRepository>
</pluginRepositories>


<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>com.google.protobuf.tools</groupId>
<artifactId>maven-protoc-plugin</artifactId>
<version>0.3.2</version>
<configuration>
<protocExecutable>/usr/bin/protoc</protocExecutable>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-pubsub</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-java6</artifactId>
<version>1.15.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
11 changes: 11 additions & 0 deletions examples/emm-notifications/settings.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Create new service account at https://console.developers.google.com
ServiceAccountEmail=changeme@gserviceaccount.com
ServiceAccountP12KeyFile=/path/to/key.p12

# This will be the name of the service account you will create
ProjectName=sample-project-name
SubscriptionName=projects/sample-project-name/subscriptions/default
TopicName=projects/sample-project-name/topics/default

# Define new push endpoint in developer console project
PushEndpoint=sample.push.endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.google.android.work.emmnotifications;

import com.google.android.work.pubsub.EmmPubsub;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.model.PublishRequest;
import com.google.api.services.pubsub.model.PubsubMessage;
import com.google.api.services.pubsub.model.Topic;
import com.google.common.collect.ImmutableList;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.logging.Logger;

/**
* This is a faux publisher which can be used to simulate messages that would be normally sent by
* Play for Work API
*
* To run this sample code:
* <ol>
* <li>Modify settings.properties or specify a different file via DEVELOPER_CONSOLE_SETTINGS
* environment variable</li>
* <li>Build a deploy jar using <code>mvn clean compile assembly:single</code></li>
* <li>Execute it as <code>
* java -cp target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar \
* com.google.android.work.emmnotifications.FauxPublisher</code></li>
* </ol>

*/
public class FauxPublisher {

private static final Logger LOG =
Logger.getLogger(FauxPublisher.class.getName());

public static void main(String[] args)
throws IOException, GeneralSecurityException {

Pubsub pubsubClient = ServiceAccountConfiguration.createPubsubClient(
Settings.getSettings().getServiceAccountEmail(),
Settings.getSettings().getServiceAccountP12KeyPath());
String topicName = Settings.getSettings().getTopicName();

try {
Topic topic = pubsubClient
.projects()
.topics()
.get(topicName)
.execute();

LOG.info("Topic " + topicName + " exists: " + topic.toPrettyString());
} catch (HttpResponseException e) {
if (e.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
// Topic doesn't exist?
LOG.info("Topic " + topicName + " doesn't exists, creating it");
pubsubClient
.projects()
.topics()
.create(topicName, new Topic())
.execute();
LOG.info("Topic " + topicName + " created");
}
}

ImmutableList.Builder<PubsubMessage> listBuilder = ImmutableList.builder();

EmmPubsub.MdmPushNotification mdmPushNotification = EmmPubsub.MdmPushNotification.newBuilder()
.addProductApprovalEvent(EmmPubsub.ProductApprovalEvent.newBuilder()
.setApproved(false)
.setProductId("com.google.android.gms")
.setCommonEventInformation(EmmPubsub.MdmNotificationEnterpriseEventCommon.newBuilder()
.setEnterpriseId("12321321")
.setEventNotificationSentTimestamp("right now")))
.build();

PublishRequest publishRequest = new PublishRequest()
.setMessages(ImmutableList.of(new PubsubMessage()
.encodeData(mdmPushNotification.toByteArray())));

LOG.info("Publishing a request: " + publishRequest.toPrettyString());

pubsubClient
.projects()
.topics()
.publish(topicName, publishRequest)
.execute();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.google.android.work.emmnotifications;

import com.google.android.work.pubsub.EmmPubsub;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.json.JsonParser;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.model.PubsubMessage;
import com.google.api.services.pubsub.model.PushConfig;
import com.google.api.services.pubsub.model.Subscription;
import com.google.common.io.CharStreams;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* This is a sample subscriber code. To run it you need to have an SSL endpoint configured
* and run this code either on port 443 (update below) on the server backing this endpoint or
* configure a reverse proxy from port 443 to 8093.
*
* Details: [link will be here]
*
* To run this sample code:
* <ol>
* <li>Modify settings.properties or specify a different file via DEVELOPER_CONSOLE_SETTINGS
* environment variable</li>
* <li>Build a deploy jar using <code>mvn clean compile assembly:single</code></li>
* <li>Execute it as <code>
* java -cp target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar \
* com.google.android.work.emmnotifications.PushSubscriber</code></li>
* </ol>
*/
public class PushSubscriber {
// this can be any port
private static final int PORT = 8093;

private static final Logger LOG = Logger.getLogger(PushSubscriber.class.getName());
public static final String MESSAGE_FIELD = "message";

public static void main(String[] args) throws Exception {
Pubsub client = ServiceAccountConfiguration.createPubsubClient(
Settings.getSettings().getServiceAccountEmail(),
Settings.getSettings().getServiceAccountP12KeyPath());

// First we check if subscription actually exists for this subscription name.
Subscription subscription = null;

String topicName = Settings.getSettings().getTopicName();
String subName = Settings.getSettings().getSubscriptionName();

LOG.info("Will be using topic name: " + topicName + ", subscription name: " + subName);

try {
LOG.info("Trying to get subscription named " + subName);
subscription = client
.projects()
.subscriptions()
.get(subName)
.execute();

LOG.info("Will be re-using existing subscription: " + subscription.toPrettyString());
} catch (HttpResponseException e) {

// subscription not found
if (e.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
LOG.info("Subscription doesn't exist, will try to create " + subName);

// Creating subscription
subscription = client
.projects()
.subscriptions()
.create(subName, new Subscription()
.setTopic(topicName) // Name of the topic it subscribes to
.setAckDeadlineSeconds(600)
.setPushConfig(new PushConfig()
// FQDN with valid SSL certificate
.setPushEndpoint(Settings.getSettings().getPushEndpoint())))
.execute();

LOG.info("Created: " + subscription.toPrettyString());
}
}

// Kicking off HttpServer which will listen on specified port and process all
// incoming push pub/sub notifications
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), 0);
server.createContext("/", new HttpHandler() {
public void handle(HttpExchange httpExchange) throws IOException {
String rawRequest = CharStreams.toString(
new InputStreamReader(httpExchange.getRequestBody()));
LOG.info("Raw request: " + rawRequest);

try {
// Note, that documentation says this is PubsubMessage, which it isn't
JsonParser parser = JacksonFactory.getDefaultInstance().createJsonParser(rawRequest);
parser.skipToKey(MESSAGE_FIELD);

PubsubMessage message = parser.parseAndClose(PubsubMessage.class);
LOG.info("Pubsub message received: " + message.toPrettyString());

// Decoding Protocol Buffers message from array of bytes
EmmPubsub.MdmPushNotification mdmPushNotification = EmmPubsub.MdmPushNotification
.newBuilder()
.mergeFrom(message.decodeData())
.build();

LOG.info("Message received: " + mdmPushNotification.toString());
} catch (Throwable e) {
LOG.log(Level.WARNING, "Error occured when decoding message", e);
}

// CloudPubSub will interpret 2XX as ACK, anything that isn't 2XX will trigger a retry
httpExchange.sendResponseHeaders(204, 0);
httpExchange.close();
}
});

server.setExecutor(null);
server.start(); // Will keep running until killed
}
}
Loading