
com.aliyun.mns.client.CloudTopic Maven / Gradle / Ivy
Show all versions of aliyun-sdk-mns Show documentation
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.aliyun.mns.client;
import com.aliyun.mns.client.impl.topic.CreateTopicAction;
import com.aliyun.mns.client.impl.topic.DeleteTopicAction;
import com.aliyun.mns.client.impl.topic.GetSubscriptionAttrAction;
import com.aliyun.mns.client.impl.topic.GetTopicAttrAction;
import com.aliyun.mns.client.impl.topic.ListSubscriptionAction;
import com.aliyun.mns.client.impl.topic.PublishMessageAction;
import com.aliyun.mns.client.impl.topic.SetSubscriptionAttrAction;
import com.aliyun.mns.client.impl.topic.SetTopicAttrAction;
import com.aliyun.mns.client.impl.topic.SubscribeAction;
import com.aliyun.mns.client.impl.topic.UnsubscribeAction;
import com.aliyun.mns.common.ClientException;
import com.aliyun.mns.common.MNSConstants;
import com.aliyun.mns.common.ServiceException;
import com.aliyun.mns.common.auth.ServiceCredentials;
import com.aliyun.mns.common.http.ServiceClient;
import com.aliyun.mns.model.AttributesValidationResult;
import com.aliyun.mns.model.MessageAttributes;
import com.aliyun.mns.model.PagingListResult;
import com.aliyun.mns.model.RawTopicMessage;
import com.aliyun.mns.model.SubscriptionMeta;
import com.aliyun.mns.model.TopicMessage;
import com.aliyun.mns.model.TopicMeta;
import com.aliyun.mns.model.request.topic.CreateTopicRequest;
import com.aliyun.mns.model.request.topic.DeleteTopicRequest;
import com.aliyun.mns.model.request.topic.GetSubscriptionAttrRequest;
import com.aliyun.mns.model.request.topic.GetTopicAttrRequest;
import com.aliyun.mns.model.request.topic.ListSubscriptionRequest;
import com.aliyun.mns.model.request.topic.PublishMessageRequest;
import com.aliyun.mns.model.request.topic.SetSubscriptionAttrRequest;
import com.aliyun.mns.model.request.topic.SetTopicAttrRequest;
import com.aliyun.mns.model.request.topic.SubscribeRequest;
import com.aliyun.mns.model.request.topic.UnsubscribeRequest;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CloudTopic {
/**
* log4j object
*/
public static Logger logger = LoggerFactory.getLogger(CloudTopic.class);
/**
* object connect to MNS service
*/
private ServiceClient serviceClient;
/**
* topic url, ie: http://uid.mns.region.aliyuncs.com/topics/topicName
*/
private String topicURL;
/**
* object content user auth info
*/
private ServiceCredentials credentials;
/**
* user mns endpoint, ie: http://uid.mns.region.aliyuncs.com/
*/
private URI endpoint;
private String accountId;
private String region;
private Map customHeaders = null;
/**
* @param topicName, topic name
* @param client, ServiceClient object
* @param credentials, ServiceCredentials object
* @param endpoint, user mns endpoint, ie: http://uid.mns.region.aliyuncs.com/
*/
protected CloudTopic(String topicName, ServiceClient client,
ServiceCredentials credentials, URI endpoint) {
this.serviceClient = client;
this.credentials = credentials;
this.endpoint = endpoint;
if (StringUtils.isEmpty(topicName)) {
throw new NullPointerException("TopicName can not be empty.");
}
String host = endpoint.getHost();
String[] hostPieces = host.split("\\.");
this.accountId = hostPieces[0];
this.region = hostPieces[2].split("-internal")[0];
String uri = endpoint.toString();
if (!uri.endsWith("/")) {
uri += "/";
}
uri += MNSConstants.TOPIC_PREFIX + topicName;
this.topicURL = uri;
}
void setCustomHeaders(Map customHeaders) {
this.customHeaders = customHeaders;
}
/**
* get topic name from topic url
*
* @return topic name
*/
private String getTopicName() {
String topicName = null;
if (topicURL.startsWith(this.endpoint.toString())) {
topicName = topicURL
.substring(this.endpoint.toString().length() + 1 + MNSConstants.TOPIC_PREFIX.length());
}
// erase start "/"
while (topicName != null && !topicName.trim().isEmpty()
&& topicName.startsWith("/")) {
topicName = topicName.substring(1);
}
if (topicName == null || topicName.trim().isEmpty()) {
logger.warn("topic name is null or empty");
throw new NullPointerException("Topic Name can not be null.");
}
return topicName;
}
/**
* get topic url
*
* @return topic url
*/
public String getTopicURL() {
return topicURL;
}
/**
* create topic with default topic meta
*
* @return topic url
*/
public String create() throws ServiceException {
String topicName = this.getTopicName();
TopicMeta meta = new TopicMeta();
meta.setTopicName(topicName);
meta.setTopicURL(this.topicURL);
return create(meta);
}
/**
* create topic with special topic meta
*
* @param meta, topic meta data
* @return topic url
*/
public String create(TopicMeta meta) throws ServiceException {
CreateTopicAction action = new CreateTopicAction(serviceClient, credentials, endpoint);
CreateTopicRequest request = new CreateTopicRequest();
request.setRequestPath(this.topicURL);
String topicName = getTopicName();
if (meta == null) {
meta = new TopicMeta();
meta.setTopicName(topicName);
meta.setTopicURL(this.topicURL);
logger.debug("topic meta is null, we use default meta");
}
if (meta.getTopicName() == null || meta.getTopicName().trim().isEmpty()) {
meta.setTopicName(topicName);
meta.setTopicURL(this.topicURL);
logger.debug("topic name in meta is null or empty, we get it from topic url");
}
if (!meta.getTopicName().equals(topicName)) {
logger.warn("TopicName conflict between meta topic name and topic url offered");
throw new ClientException("TopicName conflict between meta topic name and topic url offered",
action.getUserRequestId());
}
request.setTopicMeta(meta);
request.setRequestPath(MNSConstants.TOPIC_PREFIX + topicName);
return action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async set topic attribute with given meta and callback object
*
* @param meta, tpoic meta data
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncSetAttribute(TopicMeta meta, AsyncCallback callback) throws ServiceException {
SetTopicAttrAction action = new SetTopicAttrAction(serviceClient, credentials, endpoint);
SetTopicAttrRequest request = new SetTopicAttrRequest();
request.setTopicMeta(meta);
request.setRequestPath(MNSConstants.QUEUE_PREFIX + meta.getTopicName());
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* get topic attribute
*
* @return topic meta data
*/
public TopicMeta getAttribute() throws ServiceException {
GetTopicAttrAction action = new GetTopicAttrAction(serviceClient, credentials, endpoint);
GetTopicAttrRequest request = new GetTopicAttrRequest();
request.setRequestPath(topicURL);
TopicMeta meta = action.executeWithCustomHeaders(request, customHeaders);
meta.setTopicURL(topicURL);
return meta;
}
/**
* set tpoic attribute with given meta
*
* @param meta, topic meta data
*/
public void setAttribute(TopicMeta meta) throws ServiceException {
SetTopicAttrAction action = new SetTopicAttrAction(serviceClient, credentials, endpoint);
SetTopicAttrRequest request = new SetTopicAttrRequest();
request.setTopicMeta(meta);
request.setRequestPath(MNSConstants.TOPIC_PREFIX + meta.getTopicName());
action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async get topic attribute
*
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncGetAttribute(AsyncCallback callback) throws ServiceException {
GetTopicAttrAction action = new GetTopicAttrAction(serviceClient, credentials, endpoint);
GetTopicAttrRequest request = new GetTopicAttrRequest();
request.setRequestPath(topicURL);
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* delete topic
*/
public void delete() throws ServiceException {
DeleteTopicAction action = new DeleteTopicAction(serviceClient, credentials, endpoint);
DeleteTopicRequest request = new DeleteTopicRequest();
request.setRequestPath(topicURL);
action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async delete topic
*
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncDelete(AsyncCallback callback) throws ServiceException {
DeleteTopicAction action = new DeleteTopicAction(serviceClient, credentials, endpoint);
DeleteTopicRequest request = new DeleteTopicRequest();
request.setRequestPath(topicURL);
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* subscribe this topic
*
* @param meta, SubscriptionMeta data
* @return, subscription url
*/
public String subscribe(SubscriptionMeta meta) throws ServiceException {
if(StringUtils.isEmpty(meta.getSubscriptionName())){
throw new NullPointerException("subscriptionName can not be empty.");
}
SubscribeRequest request = new SubscribeRequest();
SubscribeAction action = new SubscribeAction(serviceClient, credentials, endpoint);
request.setMeta(meta);
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + meta.getSubscriptionName());
String url = action.executeWithCustomHeaders(request, customHeaders);
return url;
}
/**
* async subscribe this topic
*
* @param meta, SubscriptionMeta data
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncSubscribe(SubscriptionMeta meta, AsyncCallback callback)
throws ServiceException {
if(StringUtils.isEmpty(meta.getSubscriptionName())){
throw new NullPointerException("subscriptionName can not be empty.");
}
SubscribeRequest request = new SubscribeRequest();
SubscribeAction action = new SubscribeAction(serviceClient, credentials, endpoint);
request.setMeta(meta);
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + meta.getSubscriptionName());
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* set subscription attribute
*
* @param meta, SubscriptionMeta data
*/
public void setSubscriptionAttr(SubscriptionMeta meta) throws ServiceException {
if(StringUtils.isEmpty(meta.getSubscriptionName())){
throw new NullPointerException("subscriptionName can not be empty.");
}
SetSubscriptionAttrRequest request = new SetSubscriptionAttrRequest();
SetSubscriptionAttrAction action = new SetSubscriptionAttrAction(serviceClient, credentials, endpoint);
request.setMeta(meta);
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + meta.getSubscriptionName());
action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async set subscription attribute
*
* @param meta, SubscriptionMeta data
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncSetSubscriptionAttr(SubscriptionMeta meta, AsyncCallback callback)
throws ServiceException {
if(StringUtils.isEmpty(meta.getSubscriptionName())){
throw new NullPointerException("subscriptionName can not be empty.");
}
SetSubscriptionAttrRequest request = new SetSubscriptionAttrRequest();
SetSubscriptionAttrAction action = new SetSubscriptionAttrAction(serviceClient, credentials, endpoint);
request.setMeta(meta);
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + meta.getSubscriptionName());
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* get subscription attribute
*
* @param subscriptionName, subscription name
* @return SubscriptionMeta data
*/
public SubscriptionMeta getSubscriptionAttr(String subscriptionName) throws ServiceException {
GetSubscriptionAttrRequest request = new GetSubscriptionAttrRequest();
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + subscriptionName);
GetSubscriptionAttrAction action = new GetSubscriptionAttrAction(serviceClient, credentials, endpoint);
return action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async get subscription attribute
*
* @param subscriptionName, subscription name
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncGetSubscriptionAttr(String subscriptionName,
AsyncCallback callback) throws ServiceException {
GetSubscriptionAttrRequest request = new GetSubscriptionAttrRequest();
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + subscriptionName);
GetSubscriptionAttrAction action = new GetSubscriptionAttrAction(serviceClient, credentials, endpoint);
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* unsubscribe this topic
*
* @param subscriptionName, subscription name
*/
public void unsubscribe(String subscriptionName) throws ServiceException {
UnsubscribeRequest request = new UnsubscribeRequest();
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + subscriptionName);
UnsubscribeAction action = new UnsubscribeAction(serviceClient, credentials, endpoint);
action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async unsubscribe
*
* @param subscriptionName, subscription name
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncUnsubscribe(String subscriptionName, AsyncCallback callback)
throws ServiceException {
UnsubscribeRequest request = new UnsubscribeRequest();
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION + "/" + subscriptionName);
UnsubscribeAction action = new UnsubscribeAction(serviceClient, credentials, endpoint);
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
/**
* list topic subscription
*
* @param prefix, subscription name prefis
* @param marker, subscription start marker
* @param retNumber, return number
* @param withMeta, true return full SubscriptionMeta, false return only subscription url
* @return SubscriptionMeta list
*/
private PagingListResult listSubscriptions(String prefix, String marker,
Integer retNumber, boolean withMeta) throws ServiceException {
ListSubscriptionRequest request = new ListSubscriptionRequest();
ListSubscriptionAction action = new ListSubscriptionAction(serviceClient, credentials, endpoint);
request.setRequestPath(topicURL + "/" + MNSConstants.SUBSCRIPTION);
request.setMarker(marker);
request.setPrefix(prefix);
request.setMaxRet(retNumber);
request.setWithMeta(withMeta);
return action.executeWithCustomHeaders(request, customHeaders);
}
/**
* list topic subscription
*
* @param prefix, subscription name prefis
* @param marker, subscription start marker
* @param retNumber, return number
* @return SubscriptionMeta list
*/
public PagingListResult listSubscriptions(String prefix, String marker, Integer retNumber)
throws ServiceException {
return listSubscriptions(prefix, marker, retNumber, true);
}
/**
* list topic subscription
*
* @param prefix, subscription name prefis
* @param marker, subscription start marker
* @param retNumber, return number
* @return subscription url list
*/
public PagingListResult listSubscriptionUrls(String prefix, String marker, Integer retNumber)
throws ServiceException {
PagingListResult list = listSubscriptions(prefix, marker, retNumber, false);
PagingListResult result = null;
if (list != null && list.getResult() != null) {
List tmp = new ArrayList();
for (SubscriptionMeta meta : list.getResult()) {
tmp.add(meta.getSubscriptionURL());
}
result = new PagingListResult();
result.setResult(tmp);
result.setMarker(list.getMarker());
}
return result;
}
/**
* generate queue endpoint for subscription
*
* @param queueName queueName
* @return queue endpoint
*/
public String generateQueueEndpoint(String queueName) {
return "acs:mns:" + this.region + ":" + this.accountId + ":queues/" + queueName;
}
public String generateQueueEndpoint(String queueName, String region) {
return "acs:mns:" + region + ":" + this.accountId + ":queues/" + queueName;
}
/**
* generate mail endpoint for subscription
*
* @param mailAddress mailAddress
* @return mail endpoint
*/
public String generateMailEndpoint(String mailAddress) {
return "mail:directmail:" + mailAddress;
}
/**
* generate dayu endpoint for subscription
*
* @param phone phone
* @return dayu endpoint
*/
public String generateDayuEndpoint(String phone) {
return "sms:dayu:" + phone;
}
/**
* generate push endpoint for subscription
*
* @param appKey appKey
* @return push endpoint
*/
public String generatePushEndpoint(String appKey) {
return "push:" + appKey;
}
/**
* generate sms endpoint for subscription
*
* @param phone phone
* @return sms endpoint
*/
public String generateSmsEndpoint(String phone) {
return "sms:directsms:" + phone;
}
public String generateSmsEndpoint() {
return "sms:directsms:anonymous";
}
/**
* generate batch sms endpoint for subscription
*
* @return batch sms endpoint
*/
public String generateBatchSmsEndpoint() {
return "sms:directsms:anonymous";
}
/**
* publish message to topic
*
* @param msg, message,这里可以使用RawTopicMessage跟Base64TopicMessage作为向服务发消息的结构。
* Base64TopicMessage会将消息体进行base64编码。
* RawTopicMessage发送的数据是明文可读的串,我们不做任何改动。
* 如果你是用Base64TopicMessage发送消息的,那么在endpoint端收到消息时,
* 需要额外做一次base64解码,才能跟你发送的消息相匹配。
*
* 如果接收端包含了邮箱,请使用publishMessage(RawTopicMessage, MessageAttributes)
* @return message
*/
public TopicMessage publishMessage(TopicMessage msg) throws ServiceException {
PublishMessageRequest request = new PublishMessageRequest();
request.setMessage(msg);
PublishMessageAction action = new PublishMessageAction(serviceClient, credentials, endpoint);
request.setRequestPath(topicURL + "/" + MNSConstants.LOCATION_MESSAGES);
return action.executeWithCustomHeaders(request, customHeaders);
}
/**
* publish raw message to topic
*
* @param msg, RawTopicMessage发送的数据是明文可读的串,我们不做任何改动。
*
* 如果接收端是邮箱,那么这里的msg就是邮件正文.
* @param messageAttributes 如果希望被推送到邮箱,那么attributes需要包含发送邮件所必须的几个属性
* @return message
*/
public TopicMessage publishMessage(RawTopicMessage msg, MessageAttributes messageAttributes)
throws ServiceException {
PublishMessageAction action = new PublishMessageAction(serviceClient, credentials, endpoint);
AttributesValidationResult result = messageAttributes.validate();
if (!result.isSuccess()) {
throw new ClientException(result.getMessage(), action.getUserRequestId());
}
PublishMessageRequest request = new PublishMessageRequest();
request.setMessage(msg);
request.setMessageAttributes(messageAttributes);
request.setRequestPath(topicURL + "/" + MNSConstants.LOCATION_MESSAGES);
return action.executeWithCustomHeaders(request, customHeaders);
}
/**
* async publish message, we will do base64 encode for message body before publish it to MNS server.
* so, when you receive this message, you should do base64 decode before use it.
*
* @param msg, message,这里可以使用RawTopicMessage跟Base64TopicMessage作为向服务发消息的结构。
* 但我们推荐使用Base64TopicMessage,它会将消息体进行base64编码后再发送数据。
* RawTopicMessage发送的数据是明文可读的串,我们不做任何改动。
* 如果你是用Base64TopicMessage发送消息的,那么在endpoint端收到的消息,
* 需要额外做一次base64解码,才能跟你发送的消息相匹配。
* @param callback, user callback object
* @return AsyncResult, you can wait result by AsyncResult if you want to do this
*/
public AsyncResult asyncPublishMessage(TopicMessage msg, AsyncCallback callback)
throws ServiceException {
PublishMessageRequest request = new PublishMessageRequest();
request.setMessage(msg);
PublishMessageAction action = new PublishMessageAction(serviceClient, credentials, endpoint);
request.setRequestPath(topicURL + "/" + MNSConstants.LOCATION_MESSAGES);
return action.executeWithCustomHeaders(request, callback, customHeaders);
}
}