Thiết lập máy chủ cho thông báo đẩy

Google Play tạo thông báo để phản hồi các sự kiện xảy ra và có thể ảnh hưởng đến doanh nghiệp. Nhà cung cấp giải pháp EMM có thể nhận được thông báo và hành động dựa trên các thông báo đó, bằng cách đưa ra cảnh báo hoặc các cơ chế khác để quản trị viên khách hàng của mình.

Hướng dẫn này cho bạn biết cách định cấu hình cơ sở hạ tầng máy chủ cần thiết để chỉ nhận và xử lý thông báo đẩy của EMM. Bạn không cần phải thiết lập thông báo lấy dữ liệu được nêu chi tiết trong hướng dẫn này.

Ngoài cách thiết lập máy chủ được mô tả trong hướng dẫn này, đối với thông báo đẩy bạn cũng phải cấp đặc quyền thích hợp và thực hiện việc định cấu hình khác trong Bảng điều khiển API của Google. Xem Bật thông báo đẩy của EMM để biết thông tin chi tiết.

Để biết thêm thông tin về Google Cloud Pub/Sub, bao gồm cả các ví dụ, hãy xem Tài liệu về Cloud Pub/Sub.

Bạn có thể định cấu hình hệ thống của mình để thông báo đẩy được gửi đến điểm cuối HTTPS đã chỉ định hoặc đến một máy chủ chờ gửi thông báo.

Giới thiệu về cấu hình điểm cuối đẩy

Để định cấu hình điểm cuối đẩy, bạn cần một máy chủ có chứng chỉ SSL hợp lệ. Trong trong ví dụ này, bạn tạo và tải chứng chỉ SSL lên một tổ chức phát hành chứng chỉ (CA), sau đó định cấu hình máy chủ NGINX. Cuối cùng, bạn biên dịch và chạy mã kiểm thử để xác nhận rằng bạn đã thiết lập chính xác.

Ví dụ này cho biết cách định cấu hình một Máy chủ NGINX trong chế độ proxy ngược để kết nối với ứng dụng của người đăng ký (trong PushSubscriber.java) chạy trên cổng 8093, sử dụng Ubuntu 14.04. Doanh nghiệp của bạn có thể sử dụng một máy chủ nhưng thiết lập mẫu sẽ hoạt động mà không cần thay đổi trên tất cả các nền tảng dựa trên Debian Google Cloud. Các bản phân phối khác (chẳng hạn như những bản phân phối dựa trên RedHat) cũng tương tự, nhưng vị trí của các tệp cấu hình có thể khác.

Trước khi có thể nhận thông báo, bạn phải định cấu hình điểm cuối đáp ứng các tiêu chí sau:

  • Bạn phải sở hữu miền và xác minh quyền sở hữu trong Bảng điều khiển API của Google.

  • Bạn phải có khả năng chạy dịch vụ trên cổng 443 (SSL).

  • Bạn phải có chứng chỉ SSL do CA ký. Chứng chỉ tự ký không hoạt động.

  • Máy chủ web bạn đang chạy phải hỗ trợ webhook.

Điểm cuối của bạn không cần phải chạy trên Google App Engine (mặc dù có thể).

Tạo và tải lên chứng chỉ SSL

1. Tạo chứng chỉ Lớp cổng bảo mật (SSL):

    myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \
      -newkey rsa:2048 -keyout cert.key -out cert.crt

Thao tác này sẽ tạo ra phản hồi sau đây. Thay thế các giá trị mẫu (chẳng hạn như push.solarmora.commyusername@myhost) với máy chủ thực tế của bạn tên, công ty, địa chỉ, v.v. trong mã sau. Bạn có thể dùng bất kỳ miền con miễn là bản ghi A của miền con này trỏ đến máy chủ của bạn.

    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. Xác minh rằng tệp chứng chỉ đã được tạo:

$ myusername@myhost:/tmp$ ls cert*
cert.crt  cert.key

3. Để ký chứng chỉ này, hãy tạo một yêu cầu ký chứng chỉ (CSR) để tải lên người ký:

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. Đảm bảo rằng nội dung của tệp CSR có dạng như sau:

    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. Tải một phần chứng chỉ của bạn lên giữa BEGINEND dòng (bao gồm) CA của bạn. Quy trình chính xác sẽ tuỳ thuộc vào CA của bạn, nhưng sẽ bao gồm các bước sau:

  1. Tải tệp CSR lên trang web CA của bạn hoặc dán nội dung tệp vào trang web CA của bạn. Sau đó, CA của bạn sẽ xác thực và xử lý dữ liệu này.
  2. Tải xuống chứng chỉ đã ký do CA của bạn tạo.

6. Đầu ra của CA phải chứa nhiều tệp: tệp đã ký và chứng chỉ của CA xác nhận rằng họ đủ điều kiện ký chứng chỉ. Ghép tất cả tệp chứng chỉ *.crt trong tệp đã tải xuống gói thành một tệp gói, ví dụ: bundle.push.solarmora.com.crt:

$ cat *.crt > bundle.push.solarmora.com.crt

Định cấu hình máy chủ proxy

Trong phần này, bạn định cấu hình máy chủ web nguồn mở NGINX và đảo ngược máy chủ proxy để phân phát điểm cuối và chuyển tiếp tất cả yêu cầu đến đến máy chủ của người đăng ký. NGINX được dùng làm ví dụ, nhưng bạn có thể sử dụng bất kỳ Thay vào đó, hãy sử dụng proxy HTTP.

1. Cài đặt NGINX trên máy chủ của bạn:

    $ sudo apt-get update
    $ sudo apt-get install nginx
    $ nginx -v
    $ nginx version: nginx/1.4.6 (Ubuntu)

2. Để đảm bảo rằng các tệp mô tả máy chủ bổ sung mà bạn tạo trong Thư mục sites-enabled do NGINX xử lý, hãy chỉnh sửa /etc/nginx/nginx.conf và bao gồm các thành phần sau:

    $ include /etc/nginx/conf.d/*.conf;
    $ include /etc/nginx/sites-enabled/*;

3. Sao chép tệp chứng chỉ của bạn vào một vị trí an toàn, có thể đọc bằng Người dùng www-data, nhưng tốt nhất là không người dùng nào khác đọc được (có thể bạn cần để điều chỉnh tên người dùng nếu máy chủ web của bạn đang chạy dưới dạng người dùng):

    $ 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. Tạo một cấu hình server mới. Chỉnh sửa push.solarmora.com trong /etc/nginx/sites-enabled và sử dụng tên miền đủ điều kiện của máy chủ làm tên tệp:

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. Khởi động lại NGINX để triển khai các thay đổi:

    myusername@myhost:/etc/nginx$ sudo service nginx restart
    * Restarting nginx nginx
    ...done.

6. Máy chủ của bạn hiện đã được định cấu hình. Để xác minh cấu hình này, hãy thử truy vấn máy chủ của bạn bằng 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>

Đây là phản hồi dự kiến vì chưa có máy chủ xuôi dòng nào được định cấu hình (localhost:8093 trong tệp cấu hình).

Biên dịch và chạy ví dụ

Để chạy các ví dụ trong phần này, bạn cần có một Google API Console đang hoạt động dự án. Bạn nên tạo một tài khoản riêng cho mục đích thử nghiệm và tách biệt dự án đó với dự án sản xuất. Sau khi tạo một dự án thử nghiệm, bạn cần tạo một tài khoản dịch vụ. Ghi lại địa chỉ email của tài khoản dịch vụ rồi đặt tệp .p12 liên kết vào vị trí nào đó trên máy chủ của bạn.

Thiết lập cây mã nguồn

1. Sao chép kho lưu trữ 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. Trên các hệ thống dựa trên Debian, hãy cài đặt cả Maven và thời gian Trình biên dịch Vùng đệm giao thức của Google:
    $ sudo apt-get install maven protobuf-compiler

3. Xác minh rằng cả Maven và trình biên dịch Vùng đệm giao thức của Google đều được được cài đặt đúng cách:

    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. Tệp cấu hình Maven pom.xml giả định rằng trình biên dịch Vùng đệm giao thức được cài đặt vào thư mục /usr/bin/protoc:

    myusername@myhost:~$ which protoc
    /usr/bin/protoc
Nếu trường hợp này không xảy ra, bạn có thể sửa đổi pom.xml hoặc protoc liên kết tượng trưng:
    $ sudo ln -s which protoc /usr/bin/protoc
5 điểm. Biên dịch ví dụ. Xác minh rằng bạn có thể tạo mã bằng cách chạy mvn clean compile assembly:single. Thao tác này sẽ tạo ra một tệp có tên emm-notifications-[version-number]-jar-with-dependencies.jar, trong đó [version number] là phiên bản hiện tại của ví dụ này, ví dụ như 1.0-SNAPSHOT:
    myusername@myhost:~/code/play-work/examples/emm-notifications$ ls target/*
    target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
6. Xác minh rằng bạn có thể chạy mã TestPublisher đã biên dịch. Dự kiến mã này sẽ bị lỗi:

    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. Bạn phải ghi đè một số giá trị trong tệp settings.properties. Để thực hiện việc này, tạo bản sao của tệp và sửa đổi các thuộc tính trong bản sao như sau:

    # 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. Chạy lại mã TestPublisher để đảm bảo mã không còn gặp sự cố nữa. (Bạn có thể thấy một lỗi trong đầu ra nhật ký.)

Chạy mã thử nghiệm dành cho nhà xuất bản

Bạn cần chạy mã mẫu cho thông báo xuất bản để người đăng ký có một số tin nhắn cần đọc.

Trong ví dụ sau, mã tìm kiếm chủ đề được chỉ định trong my_settings.properties nhưng không tìm thấy chủ đề đó. Do đó, chủ đề này sẽ tạo chủ đề. Sau đó, công cụ này sẽ đăng một thông báo về chủ đề đó. Ví dụ này cung cấp thông tin có giá trị công cụ kiểm tra cho phép bạn mô phỏng tin nhắn do API EMM của Google Play gửi.

    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}]}

Chạy mã thử nghiệm dành cho người đăng ký

Mã thử nghiệm của người đăng ký xác nhận rằng bạn có thể nhận tin nhắn được đăng bởi mã TestPublisher.

1. Hãy đảm bảo rằng mã của bạn đã được cập nhật và biên dịch, sau đó chạy lệnh mã kiểm tra dành cho người đăng ký:

    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" }
Người đăng ký hiện đang chạy và sẵn sàng nhận cuộc gọi đến tin nhắn.

2. Chạy lại nhà xuất bản và các thông báo mới sẽ đã thêm vào nhật ký:

    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 }
Thư đã được nhận và xử lý đúng cách.