Google Play генерирует уведомления в ответ на события, которые происходят и могут повлиять на предприятие. Поставщики решений EMM могут получать эти уведомления и реагировать на них, например, предоставляя оповещения или другие механизмы для своих администраторов клиентов.
В этом руководстве рассказывается, как настроить серверную инфраструктуру, необходимую для получения и обработки только push- уведомлений EMM. Уведомления по запросу не требуют настройки, подробно описанной в этом руководстве.
Помимо настройки сервера, описанной в этом руководстве, для push-уведомлений вам также необходимо предоставить соответствующие привилегии и выполнить другие задачи настройки в консоли Google API. Подробности см. в разделе «Включение push-уведомлений EMM» .
Дополнительную информацию о Google Cloud Pub/Sub, включая примеры, см. в документации Cloud Pub/Sub .
Вы можете настроить свою систему так, чтобы push-уведомления отправлялись на указанную конечную точку HTTPS или на сервер, который ожидает отправки уведомлений.
О настройке конечной точки push-уведомлений
Чтобы настроить конечную точку принудительной отправки, вам понадобится сервер с действительным сертификатом SSL. В этом примере вы создаете и загружаете сертификат SSL в центр сертификации (CA), а затем настраиваете сервер NGINX. Наконец, вы компилируете и запускаете тестовый код, чтобы подтвердить правильность настроек.
В этом примере показано, как настроить сервер NGINX в режиме обратного прокси-сервера для подключения к приложению подписчика (в PushSubscriber.java
), работающему на порту 8093, с использованием Ubuntu 14.04. Ваше предприятие может использовать другой сервер, но пример установки должен работать без изменений во всех дистрибутивах на основе Debian. Другие дистрибутивы (например, основанные на RedHat) аналогичны, но расположение файлов конфигурации может быть другим.
Прежде чем вы сможете получать уведомления, вы должны настроить конечную точку, соответствующую следующим критериям:
Вы должны быть владельцем домена и подтвердить свое право собственности в консоли Google API .
У вас должна быть возможность запустить службу на порту 443 (SSL).
У вас должен быть SSL-сертификат, подписанный центром сертификации. Самоподписанные сертификаты не работают.
Веб-сервер, который вы используете, должен поддерживать веб-перехватчики .
Ваша конечная точка не обязательно должна работать на Google App Engine (хотя это возможно).
Создайте и загрузите сертификат SSL
1. Создайте сертификат Secure Sockets Layer (SSL):
myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout cert.key -out cert.crt
Это генерирует следующий ответ. Замените примеры значений (например, push.solarmora.com
и myusername@myhost
) фактическим именем вашего сервера, компанией, адресом и т. д. в следующем коде. Вы можете использовать любой субдомен, если запись A
этого субдомена указывает на ваш сервер.
Generating a 2048 bit RSA private key ........................................................................... .....+++ writing new private key to 'cert.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:GB State or Province Name (full name) [Some-State]:England Locality Name (eg, city) []:London Organization Name (eg, company) [Internet Widgits Pty Ltd]:Solarmora, Inc. Organizational Unit Name (eg, section) []:Creative Publications Common Name (e.g. server FQDN or YOUR name) []:push.solarmora.com Email Address []:admin@solarmora.com
2. Убедитесь, что файл сертификата создан:
$ myusername@myhost:/tmp$ ls cert*
cert.crt cert.key
3. Чтобы подписать этот сертификат, создайте запрос на подпись сертификата (CSR) и загрузите его подписывающей стороне:
myusername@myhost:/tmp$ sudo openssl x509 -x509toreq -in cert.crt \ -out cert.csr -signkey cert.key Getting request Private Key Generating certificate request
myusername@myhost:/tmp$ ls cert.* cert.crt cert.csr cert.key
4. Убедитесь, что содержимое файла CSR выглядит следующим образом:
Certificate Request: Data: Version: 0 (0x0) Subject: C=GB, ST=England, L=London, O=Solarmora, Inc., OU=Creative Publications, CN=push.solarmora.com/emailAddress=admin@solarmora.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:cc:0f:54:26:3d:d9:17:eb:8f:6c:f7:27:5e:77: 64:65:00:db:fe:2a:1f:fa:ea:de:21:7a:c5:5d:87: ... ... Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha256WithRSAEncryption 1d:ea:12:b8:c2:6a:d6:f4:6e:92:2f:b9:12:5e:e3:91:15:a0: 06:b5:81:ce:c5:cf:b7:d2:a7:dd:f2:78:ca:28:8e:21:cd:6d: ... ... -----BEGIN CERTIFICATE REQUEST----- MIIC6zCCAdMCAQAwgaUxCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMQ8w DQYDVQQHDAZMb25kb24xGDAWBgNVBAoMD0FDTUUgQ29ycCwgSW5jLjEYMBYGA1UE CwwPQ3JlYXRpdmUgQW52aWxzMRswGQYDVQQDDBJwdXNoLmFjbWUtY29ycC5jb20x IjAgBgkqhkiG9w0BCQEWE2FkbWluQGFjbWUtY29ycC5jb20wggEiMA0GCSqGSIb3 ... ... -----END CERTIFICATE REQUEST-----
5. Загрузите часть вашего сертификата между строками BEGIN
и END
(включительно) в свой ЦС. Точный процесс будет зависеть от вашего центра сертификации и будет включать в себя следующие шаги:
- Загрузите файл CSR на сайт CA или вставьте содержимое файла на сайт CA. Затем ваш центр сертификации проверяет и обрабатывает эти данные.
- Загрузите подписанный сертификат, созданный вашим центром сертификации.
6. Выходные данные ЦС должны содержать несколько файлов: сам подписанный сертификат и сертификат ЦС, подтверждающий, что они имеют право подписывать сертификаты. Объедините все файлы сертификатов *.crt
в загруженном пакете в один файл пакета, например bundle.push.solarmora.com.crt
:
$ cat *.crt > bundle.push.solarmora.com.crt
Настройте свой прокси-сервер
В этом разделе вы настраиваете веб-сервер NGINX с открытым исходным кодом и обратный прокси-сервер для обслуживания конечной точки и пересылки всех входящих запросов на сервер подписчика. В качестве примера используется NGINX, но вместо него вы можете использовать любой другой HTTP-прокси.
1. Установите NGINX на свой сервер:
$ sudo apt-get update $ sudo apt-get install nginx $ nginx -v $ nginx version: nginx/1.4.6 (Ubuntu)
2. Чтобы гарантировать, что дополнительные файлы конфигурации сервера, которые вы создаете в каталоге sites-enabled
обрабатываются NGINX, отредактируйте /etc/nginx/nginx.conf
и включите следующее:
$ include /etc/nginx/conf.d/*.conf; $ include /etc/nginx/sites-enabled/*;
3. Скопируйте файлы сертификатов в безопасное место, доступное для чтения пользователю www-data
, но желательно недоступное для чтения любому другому пользователю (возможно, вам придется изменить имя пользователя, если ваш веб-сервер работает от имени другого пользователя):
$ sudo mkdir -p /var/openssl/push.solarmora.com $ sudo mv /tmp/cert.key
/var/openssl/push.solarmora.com/push.solarmora.com.key $ sudo mv /tmp/bundle.push.solarmora.com.crt
/var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt
4. Создайте новую конфигурацию server
. Отредактируйте push.solarmora.com
в /etc/nginx/sites-enabled
и используйте полное доменное имя вашего фактического сервера в качестве имени файла:
server {
listen 443;
server_name push.solarmora.com;
ssl on;
ssl_certificate
/var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt;
ssl_certificate_key
/var/openssl/push.solarmora.com/push.solarmora.com.key;
# it is usually very convenient to have separate files for your
# access and error log to analyze for possible problems
access_log /var/log/nginx/nginx.push.solarmora.com.log;
error_log /var/log/nginx/nginx.push.solarmora.com.log;
location / {
# assuming the subscriber will run on the same machine
# on port 8093
proxy_pass http://localhost:8093;
}
}
5. Перезапустите NGINX, чтобы изменения вступили в силу:
myusername@myhost:/etc/nginx$ sudo service nginx restart * Restarting nginx nginx ...done.
6. Ваш сервер настроен. Чтобы проверить конфигурацию, попробуйте запросить ваш сервер с помощью curl
:
[myusername@myhost:~]$ curl push.solarmora.com <html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.4.6 (Ubuntu)</center> </body> </html>
Это ожидаемый ответ, учитывая, что ни один нижестоящий сервер не настроен ( localhost:8093
в нашем файле конфигурации).
Скомпилируйте и запустите примеры
Для запуска примеров из этого раздела вам понадобится активный проект консоли Google API . Мы рекомендуем вам создать его специально для целей тестирования и хранить его отдельно от вашего производственного проекта. После создания тестового проекта вам необходимо создать сервисную учетную запись . Запишите адрес электронной почты учетной записи службы и поместите связанный файл .p12 где-нибудь на своем сервере.
Настройка дерева исходного кода
1. Клонируйте репозиторий play-work.git
:
myusername@myhost:~/code$ git clone https://github.com/google/play-work.git Cloning into 'play-work'... Username for 'https://github.com': username Password for 'https://username@github.com': remote: Counting objects: 110, done. remote: Compressing objects: 100% (60/60), done. remote: Total 110 (delta 24), reused 95 (delta 9), pack-reused 0 Receiving objects: 100% (110/110), 23.88 KiB | 0 bytes/s, done. Resolving deltas: 100% (24/24), done. Checking connectivity... done.2. В системах на базе Debian установите Maven и компилятор Google Protocol Buffers :
$ sudo apt-get install maven protobuf-compiler
3. Убедитесь, что Maven и компилятор Google Protocol Buffers установлены правильно:
myusername@myhost:~$ mvn -v Apache Maven 3.0.5 Maven home: /usr/share/maven Java version: 1.7.0_75, vendor: Oracle Corporation Java home: /usr/lib/jvm/java-7-openjdk-amd64/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "3.16.0-30-generic", arch: "amd64", family: "unix"
myusername@myhost:~$ protoc --version libprotoc 2.5.0
4. Файл конфигурации Maven pom.xml
предполагает, что компилятор протокольных буферов установлен в каталоге /usr/bin/protoc
:
myusername@myhost:~$ which protoc /usr/bin/protocЕсли это не так, вы можете изменить
pom.xml
или символическую ссылку protoc
:
$ sudo ln -s which protoc
/usr/bin/protoc
5. Скомпилируйте примеры. Убедитесь, что вы можете собрать код, запустив mvn clean compile assembly:single
. В результате должен быть создан файл с именем emm-notifications-[version-number]-jar-with-dependencies.jar
, где [version number]
— текущая версия примера, например 1.0-SNAPSHOT
:myusername@myhost:~/code/play-work/examples/emm-notifications$ ls target/* target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar6. Убедитесь, что вы можете запустить скомпилированный код
TestPublisher
. Ожидается, что код завершится неудачно:myusername@myhost:~/code/play-work/examples/emm-notifications$ java -cp \ target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar \ com.google.android.work.emmnotifications.TestPublisher Exception in thread "main" java.lang.IllegalArgumentException: You must specify non-default ServiceAccountEmail in settings.properties at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:119) at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:69) at com.google.android.work.emmnotifications.Settings.verifyVariable(Settings.java:129) at com.google.android.work.emmnotifications.Settings.getSettings(Settings.java:103) at com.google.android.work.emmnotifications.TestPublisher.main(TestPublisher.java:39)
7. Необходимо переопределить некоторые значения в файле settings.properties
. Для этого создайте копию файла и измените свойства копии следующим образом:
# This should be your own service account's email address ServiceAccountEmail=368628613713-t4hfexampledn5lhpdcu1qqfgio01626@developer.gserviceaccount.com ServiceAccountP12KeyFile=/opt/secret/secret.p12
# This will be the name of the service account ProjectName=enterprise-cloud-pub-sub SubscriptionName=projects/enterprise-cloud-pub-sub/subscriptions/default TopicName=projects/enterprise-cloud-pub-sub/topics/default
# The push endpoint in your API Console project PushEndpoint=https://push.solarmora.com
8. Запустите код TestPublisher
еще раз, чтобы убедиться, что он больше не дает сбоя. (В выводе журнала вы можете увидеть одну ошибку.)
Запустите тестовый код издателя
Вам необходимо запустить пример кода для публикации уведомлений, чтобы у вашего подписчика было несколько сообщений для чтения.
В следующем примере код ищет тему, указанную в my_settings.properties
, но не находит ее и поэтому создает тему. Затем он публикует сообщение в теме. В этом примере представлен ценный инструмент тестирования, который позволяет эмулировать сообщения, отправляемые API EMM Google Play.
myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.properties java -cp \ target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar com.google.android.work.emmnotifications.TestPublisher Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse INFO: RetryHandler: { "error": { "code": 404, "message": "Resource not found (resource=default).", "errors": [ { "message": "Resource not found (resource=default).", "domain": "global", "reason": "notFound" } ], "status": "NOT_FOUND" } } Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.TestPublisher main INFO: Topic projects/enterprise-cloud-pub-sub/topics/default doesn't exists, creating it Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main INFO: Topic projects/enterprise-cloud-pub-sub/topics/default created Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main INFO: Publishing a request: {messages=[{data=CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA}]}
Запустите тестовый код подписчика
Тестовый код подписчика подтверждает, что вы можете получать сообщения, опубликованные кодом TestPublisher
.
1. Убедитесь, что ваш код обновлен и скомпилирован, а затем запустите тестовый код подписчика:
myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.propertiesТеперь подписчик работает и готов принимать входящие сообщения.
java -cp target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
com.google.android.work.emmnotifications.PushSubscriber Feb 27, 2015 1:46:37 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Will be using topic name: projects/enterprise-cloud-pub-sub/topics/default, subscription name:
projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Trying to get subscription named projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse INFO: RetryHandler: { "error": { "code": 404, "message": "Resource not found (resource=default).", "errors": [ { "message": "Resource not found (resource=default).", "domain": "global", "reason": "notFound" } ], "status": "NOT_FOUND" } } Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Subscription doesn't exist, will try to create projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:43 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Created: { "ackDeadlineSeconds" : 600, "name" : "projects/enterprise-cloud-pub-sub/subscriptions/default", "pushConfig" : { "pushEndpoint" : "https://push.solarmora.com" }, "topic" : "projects/enterprise-cloud-pub-sub/topics/default" }
2. Снова запустите издатель, и в журнал будут добавлены новые сообщения:
Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Raw request: {"message":{"data":"CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA",Сообщение было правильно получено и обработано.
"attributes":{},"message_id":"71571141246"},"subscription":"/subscriptions/enterprise-cloud-pub-sub/default"} Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Pubsub message received: { "attributes" : { }, "data" : "CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA", "message_id" : "71571141246" } Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Message received: product_approval_event { common_event_information { enterprise_id: "12321321" event_notification_sent_timestamp: "right now" } product_id: "com.google.android.gms" approved: false }