Использование интерфейсов API REST из внутренней службы
Как описано в Управление регистрацией, обычно внутренняя служба приложения отправляет уведомления и может осуществлять управление регистрациями. Так как программа-оболочка REST для Node.js в Azure SDK для Node уже существует, в этом разделе приведены примеры на языке Java.
Отправка уведомлений
API REST для отправки уведомлений — это просто запрос POST по пути "/ваш_центр/messages" со специальными заголовками. При отправке уведомлений в собственном формате платформы отправляемый текст указывается в этом же формате. Ниже приведены дополнительные заголовки.
ServiceBusNotification-Format: Указывает платформу (если отправляется собственное уведомление) или "шаблон" для отправки шаблонного уведомления.
ServiceBusNotification-Tags (необязательно): Указывает тег (или выражение с тегами), определяющий целевой набор регистраций. Если этот заголовок не указан, центр уведомлений вещает на все регистрации.
Другие заголовки поддерживаются для платформенных функциональных возможностей, как указано в Интерфейсы API REST концентраторов уведомлений документации.
Приведенный ниже код Java отправляет собственное уведомление в приложения Магазина Windows (посредством Apache HttpClient).
public Notification createWindowsNotification(String body) { Notification n = new Notification(); n.body = body; n.headers.put("ServiceBusNotification-Format", "windows"); if (body.contains("<toast>")) n.headers.put("X-WNS-Type", "wns/toast"); if (body.contains("<tile>")) n.headers.put("X-WNS-Type", "wns/tile"); if (body.contains("<badge>")) n.headers.put("X-WNS-Type", "wns/badge"); if (body.startsWith("<")) { n.contentType = ContentType.APPLICATION_XML; } return n; } public void sendNotification(Notification notification, String tagExpression) { HttpPost post = null; try { URI uri = new URI(endpoint + hubPath + "/messages"+APIVERSION); post = new HttpPost(uri); post.setHeader("Authorization", generateSasToken(uri)); if (tagExpression != null && !"".equals(tagExpression)) { post.setHeader("ServiceBusNotification-Tags", tagExpression); } for (String header: notification.getHeaders().keySet()) { post.setHeader(header, notification.getHeaders().get(header)); } post.setEntity(new StringEntity(notification.getBody())); HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() != 201) { String msg = ""; if (response.getEntity() != null && response.getEntity().getContent() != null) { msg = IOUtils.toString(response.getEntity().getContent()); } throw new RuntimeException("Error: " + response.getStatusLine() + " body: "+msg); } } catch (Exception e) { throw new RuntimeException(e); } finally { if (post != null) post.releaseConnection(); } }
Аналогично приведенный ниже код отправляет шаблонное уведомление.
public Notification createTemplateNotification(Map<String, String> properties) { Notification n = new Notification(); StringBuffer buf = new StringBuffer(); buf.append("{"); for (Iterator<String> iterator = properties.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); buf.append("\""+ key + "\":\""+properties.get(key)+"\""); if (iterator.hasNext()) buf.append(","); } buf.append("}"); n.body = buf.toString(); n.contentType = ContentType.APPLICATION_JSON; n.headers.put("ServiceBusNotification-Format", "template"); return n; }
Дополнительные сведения Отправка уведомлений для других платформ, в разделе Интерфейсы API REST концентраторов уведомлений.
Создание и обновление регистраций
При создании и обновлении регистраций требуется сериализация и десериализация формата XML регистрации.Создание регистрации API раздела показаны форматы XML для создания различных видов регистраций (собственных и шаблонных для каждой платформы).
Важно!
Элементы XML должны быть точно в указанном порядке.
Ниже приведен пример создания регистрации на языке Java, используется для создания полезных данных XML регистрации, объединение строк и Apache Digester для анализа результата. Как было отмечено ранее, допускается любой способ сериализации или десериализации XML.
public Registration createRegistration(Registration registration) { HttpPost post = null; try { URI uri = new URI(endpoint + hubPath + "/registrations"+APIVERSION); post = new HttpPost(uri); post.setHeader("Authorization", generateSasToken(uri)); StringEntity entity = new StringEntity(registration.getXml(),ContentType.APPLICATION_ATOM_XML); entity.setContentEncoding("utf-8"); post.setEntity(entity); HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); return Registration.parse(response.getEntity().getContent()); } catch (Exception e) { throw new RuntimeException(e); } finally { if (post != null) post.releaseConnection(); } }
getXml()
Метод для собственных регистраций Windows является следующим:
private static final String WNS_NATIVE_REGISTRATION = "<?xml version=\"1.0\" encoding=\"utf-8\"?><entry xmlns=\"http://www.w3.org/2005/Atom\"><content type=\"application/xml\"><WindowsRegistrationDescription xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"https://schemas.microsoft.com/netservices/2010/10/servicebus/connect\">{0}<ChannelUri>{1}</ChannelUri>
</WindowsRegistrationDescription>
</content>
</entry>"; public String getXml() { String xml = WNS_NATIVE_REGISTRATION.replaceFirst("\\{1\\}", channelUri.toString()); xml = xml.replaceFirst("\\{0\\}", getTagsXml()); return xml.toString(); }
Методы для других типов регистраций можно легко вывести из примеров в Создание регистрации разделе API.
Ответ содержит результат создания, в том числе свойства только для чтения, например RegistrationId
, ETag
, и ExpirationTime
. Следующий пример кода выполняет синтаксический анализ результатов с помощью Apache Digester:
public static Registration parse(InputStream content) throws IOException, SAXException { Digester digester = new Digester(); digester.addObjectCreate("*/WindowsRegistrationDescription", WindowsRegistration.class); digester.addCallMethod("*/RegistrationId", "setRegistrationId", 1); digester.addCallParam("*/RegistrationId", 0); digester.addCallMethod("*/ETag", "setEtag", 1); digester.addCallParam("*/ETag", 0); digester.addCallMethod("*/ChannelUri", "setChannelUri", 1); digester.addCallParam("*/ChannelUri", 0); digester.addCallMethod("*/Tags", "setTagsFromString", 1); digester.addCallParam("*/Tags", 0); digester.addCallMethod("*/BodyTemplate", "setBodyTemplate", 1); digester.addCallParam("*/BodyTemplate", 0); digester.addCallMethod("*/WnsHeader", "addHeader", 2); digester.addCallParam("*/WnsHeader/Header", 0); digester.addCallParam("*/WnsHeader/Value", 1); return digester.parse(content); }
Обратите внимание, что Create
вызов возвращает registrationId
, который используется для извлечения, обновления или удаления регистрации.
Примечание
Предыдущем фрагменте кода предполагается, что является подклассом Registration
вызывается WindowsRegistrationDescription
.
Обновления регистрации можно, выполнив ПОМЕСТИТЬ вызвать /yourhub/registrations / {registrationId}.If-Match заголовок используется для предоставления ETag (с поддержкой оптимистичного параллелизма) или просто "*" всегда перезаписать. Если If-Match заголовок не указан, операция выполняет «upsert» (всегда перезапись текущей регистрации или создания по указанному registrationId если он отсутствует). Например:
public Registration updateRegistration(Registration registration) { HttpPut put = null; try { URI uri = new URI(endpoint + hubPath + "/registrations/"+registration.getRegistrationId()+APIVERSION); put = new HttpPut(uri); put.setHeader("Authorization", generateSasToken(uri)); put.setHeader("If-Match", registration.getEtag()==null?"*":"W/\""+registration.getEtag()+"\""); put.setEntity(new StringEntity(registration.getXml(),ContentType.APPLICATION_ATOM_XML)); HttpResponse response = httpClient.execute(put); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); return Registration.parse(response.getEntity().getContent()); } catch (Exception e) { throw new RuntimeException(e); } finally { if (put != null) put.releaseConnection(); } }
Удаление регистрации является аналогичной операцией.
Извлечение регистраций
При извлечении регистрации следует выполнить вызов GET на /registrations/{registrationId}
. Будет извлечена коллекция регистраций, как указано в приведенных API REST.
Имеется возможность указать $top возвращаемый параметр, который ограничивает количество регистраций. Если присутствуют несколько регистраций для данного запроса, а затем X-MS-ContinuationToken возвращается заголовок, который можно передавать в последующие вызовы, чтобы продолжить извлечение оставшихся регистраций. Также обратите внимание, что теперь текст указан в формате веб-канала XML Atom, как было показано в упомянутых ранее разделах об API.
Приведенный ниже код Java извлекает все регистрации с тегом.
private CollectionResult retrieveRegistrationByTag() { String queryUri = endpoint + hubPath + "/tags/"+tag+"/registrations"+APIVERSION; HttpGet get = null; try { URI uri = new URI(queryUri); get = new HttpGet(uri); get.setHeader("Authorization", generateSasToken(uri)); HttpResponse response = httpClient.execute(get); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); CollectionResult result = Registration.parseRegistrations(response.getEntity().getContent()); Header contTokenHeader = response.getFirstHeader("X-MS-ContinuationToken"); if (contTokenHeader !=null) { result.setContinuationToken(contTokenHeader.getValue()); } return result; } catch (Exception e) { throw new RuntimeException(e); } finally { if (get != null) get.releaseConnection(); } }
В этом коде CollectionResult
инкапсулирует набор регистраций, а также дополнительный маркер продолжения.
В следующем коде используется Apache Digester:
public static CollectionResult parseRegistrations(InputStream content) throws IOException, SAXException { Digester digester = new Digester(); // add all rules for parsing single registrations digester.addObjectCreate("feed", CollectionResult.class); digester.addSetNext("*/WindowsRegistrationDescription", "addRegistration"); // add rules for other types of registrations (if required) return digester.parse(content); }