diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml
index 13166321..e955b57b 100644
--- a/spring-cloud-alibaba-dependencies/pom.xml
+++ b/spring-cloud-alibaba-dependencies/pom.xml
@@ -26,6 +26,9 @@
2.16.0
4.3.1
2.1.6
+ 1.1.0
+ 1.1.8
+ 1.1.0
@@ -153,6 +156,18 @@
${oss.version}
+
+
+ com.aliyun.mns
+ aliyun-sdk-mns
+ ${aliyun.sdk.mns}
+
+
+
+ com.aliyun
+ aliyun-java-sdk-dysmsapi
+ ${aliyun.java.sdk.dysmsapi}
+
@@ -195,6 +210,11 @@
spring-cloud-alicloud-schedulerx
${project.version}
+
+ org.springframework.cloud
+ spring-cloud-alicloud-sms
+ ${project.version}
+
org.springframework.cloud
spring-cloud-alicloud-context
@@ -248,6 +268,12 @@
${project.version}
+
+ org.springframework.cloud
+ spring-cloud-starter-alicloud-sms
+ ${project.version}
+
+
org.springframework.cloud
spring-cloud-starter-stream-rocketmq
diff --git a/spring-cloud-alibaba-examples/pom.xml b/spring-cloud-alibaba-examples/pom.xml
index 3e7894dc..0eca5b82 100644
--- a/spring-cloud-alibaba-examples/pom.xml
+++ b/spring-cloud-alibaba-examples/pom.xml
@@ -28,6 +28,7 @@
ans-example/ans-provider-example
acm-example/acm-local-example
rocketmq-example
+ sms-example
spring-cloud-bus-rocketmq-example
schedulerx-example/schedulerx-simple-task-example
diff --git a/spring-cloud-alibaba-examples/sms-example/pom.xml b/spring-cloud-alibaba-examples/sms-example/pom.xml
new file mode 100644
index 00000000..c10808ff
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-alibaba-examples
+ 0.1.2.BUILD-SNAPSHOT
+
+
+ 4.0.0
+
+ alibaba.com
+ sms-example
+ jar
+
+ sms-example
+ Demo project for Spring Boot
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.cloud
+ spring-cloud-starter-alicloud-sms
+
+
+ com.google.code.gson
+ gson
+ 2.8.2
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsApplication.java b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsApplication.java
new file mode 100644
index 00000000..087ab0b0
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsApplication.java
@@ -0,0 +1,13 @@
+package org.springframework.cloud.alibaba.cloud.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SmsApplication {
+
+ public static void main(String[] args) {
+
+ SpringApplication.run(SmsApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsCode.java b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsCode.java
new file mode 100644
index 00000000..49312616
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsCode.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 the original author or authors.
+ *
+ * Licensed 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 org.springframework.cloud.alibaba.cloud.example;
+
+/**
+ * @author pbting
+ * @date 2019-01-09 2:12 PM
+ */
+public class SmsCode {
+
+ private String code;
+
+ public SmsCode(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsController.java b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsController.java
new file mode 100644
index 00000000..4585a173
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsController.java
@@ -0,0 +1,133 @@
+package org.springframework.cloud.alibaba.cloud.example;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.alicloud.sms.ISmsService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.aliyun.mns.model.Message;
+import com.aliyuncs.dysmsapi.model.v20170525.*;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.http.MethodType;
+import com.google.gson.Gson;
+
+@RestController
+public class SmsController {
+
+ @Autowired
+ private ISmsService smsService;
+
+ @Autowired
+ private SmsReportMessageListener smsReportMessageListener;
+
+ /**
+ * 短信发送 Example
+ * @param code
+ * @return
+ */
+ @RequestMapping("/batch-sms-send.do")
+ public SendBatchSmsResponse batchsendCheckCode(
+ @RequestParam(name = "code") String code) {
+ // 组装请求对象
+ SendBatchSmsRequest request = new SendBatchSmsRequest();
+ // 使用post提交
+ request.setMethod(MethodType.GET);
+ // 必填:待发送手机号。支持JSON格式的批量调用,批量上限为100个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
+ request.setPhoneNumberJson("[\"****\",\"****\",\"****\"]");
+ // 必填:短信签名-支持不同的号码发送不同的短信签名
+ request.setSignNameJson("[\"企业级分布式应用服务\",\"企业级分布式应用服务\",\"企业级分布式应用服务\"]");
+ // 必填:短信模板-可在短信控制台中找到
+ request.setTemplateCode("*****");
+ // 必填:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
+ // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
+ List smsCodes = new ArrayList<>();
+ smsCodes.add(new SmsCode(code));
+ smsCodes.add(new SmsCode(code));
+ smsCodes.add(new SmsCode(code));
+ request.setTemplateParamJson(new Gson().toJson(smsCodes));
+ // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
+ // request.setSmsUpExtendCodeJson("[\"90997\",\"90998\"]");
+ try {
+ SendBatchSmsResponse sendSmsResponse = smsService
+ .sendSmsBatchRequest(request);
+ return sendSmsResponse;
+ }
+ catch (ClientException e) {
+ e.printStackTrace();
+ }
+ return new SendBatchSmsResponse();
+ }
+
+ /**
+ * 短信发送 Example
+ * @param code
+ * @return
+ */
+ @RequestMapping("/sms-send.do")
+ public SendSmsResponse sendCheckCode(@RequestParam(name = "code") String code) {
+ // 组装请求对象-具体描述见控制台-文档部分内容
+ SendSmsRequest request = new SendSmsRequest();
+ // 必填:待发送手机号
+ request.setPhoneNumbers("****");
+ // 必填:短信签名-可在短信控制台中找到
+ request.setSignName("企业级分布式应用服务");
+ // 必填:短信模板-可在短信控制台中找到
+ request.setTemplateCode("*****");
+ // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
+ request.setTemplateParam("{\"code\":\"" + code + "\"}");
+
+ // 选填-上行短信扩展码(无特殊需求用户请忽略此字段)
+ // request.setSmsUpExtendCode("90997");
+
+ // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
+ request.setOutId("****TraceId");
+ try {
+ SendSmsResponse sendSmsResponse = smsService.sendSmsRequest(request);
+ return sendSmsResponse;
+ }
+ catch (ClientException e) {
+ e.printStackTrace();
+ }
+ return new SendSmsResponse();
+ }
+
+ /**
+ *
+ * 短信查询 Example
+ * @param telephone
+ * @return
+ */
+ @RequestMapping("/query.do")
+ public QuerySendDetailsResponse querySendDetailsResponse(
+ @RequestParam(name = "tel") String telephone) {
+ // 组装请求对象
+ QuerySendDetailsRequest request = new QuerySendDetailsRequest();
+ // 必填-号码
+ request.setPhoneNumber(telephone);
+ // 必填-短信发送的日期 支持30天内记录查询(可查其中一天的发送数据),格式yyyyMMdd
+ request.setSendDate("20190103");
+ // 必填-页大小
+ request.setPageSize(10L);
+ // 必填-当前页码从1开始计数
+ request.setCurrentPage(1L);
+ try {
+ QuerySendDetailsResponse response = smsService.querySendDetails(request);
+ return response;
+ }
+ catch (ClientException e) {
+ e.printStackTrace();
+ }
+
+ return new QuerySendDetailsResponse();
+ }
+
+ @RequestMapping("/sms-report.do")
+ public List smsReport() {
+
+ return smsReportMessageListener.getSmsReportMessageSet();
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsReportMessageListener.java b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsReportMessageListener.java
new file mode 100644
index 00000000..4f63c15c
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsReportMessageListener.java
@@ -0,0 +1,29 @@
+package org.springframework.cloud.alibaba.cloud.example;
+
+import com.aliyun.mns.model.Message;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/***
+ *
+ * @author 如果需要监听短信是否被对方成功接收,只需实现这个接口并初始化一个 Spring Bean 即可。
+ */
+@Component
+public class SmsReportMessageListener
+ implements org.springframework.cloud.alicloud.sms.SmsReportMessageListener {
+ private List smsReportMessageSet = new LinkedList<>();
+
+ @Override
+ public boolean dealMessage(Message message) {
+ smsReportMessageSet.add(message);
+ System.err.println(this.getClass().getName() + "; " + message.toString());
+ return true;
+ }
+
+ public List getSmsReportMessageSet() {
+
+ return smsReportMessageSet;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsUpMessageListener.java b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsUpMessageListener.java
new file mode 100644
index 00000000..94afb88b
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/java/org/springframework/cloud/alibaba/cloud/example/SmsUpMessageListener.java
@@ -0,0 +1,20 @@
+package org.springframework.cloud.alibaba.cloud.example;
+
+import org.springframework.stereotype.Component;
+
+import com.aliyun.mns.model.Message;
+
+/***
+ *
+ * @author 如果发送的短信需要接收对方回复的状态消息,只需实现该接口并初始化一个 Spring Bean 即可。
+ */
+@Component
+public class SmsUpMessageListener
+ implements org.springframework.cloud.alicloud.sms.SmsUpMessageListener {
+
+ @Override
+ public boolean dealMessage(Message message) {
+ System.err.println(this.getClass().getName() + "; " + message.toString());
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/sms-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/sms-example/src/main/resources/application.properties
new file mode 100644
index 00000000..cc0931c9
--- /dev/null
+++ b/spring-cloud-alibaba-examples/sms-example/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+spring.application.name=sca-sms-example
+server.port=9051
+# config management
+#config sms
+spring.cloud.alicloud.access-key=*****
+spring.cloud.alicloud.secret-key=******
+spring.cloud.alicloud.sms.report-queue-name=*****
+spring.cloud.alicloud.sms.up-queue-name=*****
+#config endpoint
+management.port=19391
+management.context-path=/test
+management.security.enabled=false
\ No newline at end of file
diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsAutoConfiguration.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsAutoConfiguration.java
index 52e35309..144520fc 100644
--- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsAutoConfiguration.java
+++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsAutoConfiguration.java
@@ -21,12 +21,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.alicloud.ans.migrate.MigrateOnConditionMissingClass;
import org.springframework.cloud.alicloud.ans.registry.AnsAutoServiceRegistration;
import org.springframework.cloud.alicloud.ans.registry.AnsRegistration;
import org.springframework.cloud.alicloud.ans.registry.AnsServiceRegistry;
+import org.springframework.cloud.alicloud.context.ans.AnsProperties;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
@@ -34,6 +38,7 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
@EnableConfigurationProperties
+@Conditional(MigrateOnConditionMissingClass.class)
@ConditionalOnClass(name = "org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent")
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
@ConditionalOnAnsEnabled
@@ -49,8 +54,9 @@ public class AnsAutoConfiguration {
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
- public AnsRegistration ansRegistration() {
- return new AnsRegistration();
+ public AnsRegistration ansRegistration(AnsProperties ansProperties,
+ ApplicationContext applicationContext) {
+ return new AnsRegistration(ansProperties, applicationContext);
}
@Bean
@@ -63,4 +69,5 @@ public class AnsAutoConfiguration {
return new AnsAutoServiceRegistration(registry, autoServiceRegistrationProperties,
registration);
}
+
}
diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java
index 34bcb64c..96d6d264 100644
--- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java
+++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java
@@ -16,42 +16,33 @@
package org.springframework.cloud.alicloud.ans;
-import java.util.*;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.alicloud.context.ans.AnsProperties;
-import org.springframework.cloud.client.DefaultServiceInstance;
+import com.alibaba.ans.core.NamingService;
+import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
+import org.springframework.cloud.alicloud.ans.registry.AnsRegistration;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
-import com.alibaba.ans.core.NamingService;
-import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
+import java.util.*;
/**
* @author xiaolongzuo
+ * @author pbting
*/
public class AnsDiscoveryClient implements DiscoveryClient {
public static final String DESCRIPTION = "Spring Cloud ANS Discovery Client";
- @Autowired
- private AnsProperties ansProperties;
+ private AnsRegistration ansRegistration;
+
+ public AnsDiscoveryClient(AnsRegistration ansRegistration) {
+ this.ansRegistration = ansRegistration;
+ }
@Override
public String description() {
return DESCRIPTION;
}
- @Override
- public ServiceInstance getLocalServiceInstance() {
- String serviceId = ansProperties.getClientDomains();
- String host = ansProperties.getClientIp();
- int port = ansProperties.getClientPort();
- boolean secure = ansProperties.isSecure();
- Map metadata = ansProperties.getClientMetadata();
- return new DefaultServiceInstance(serviceId, host, port, secure, metadata);
- }
-
@Override
public List getInstances(String serviceId) {
try {
@@ -91,8 +82,9 @@ public class AnsDiscoveryClient implements DiscoveryClient {
@Override
public List getServices() {
-
+ Set publishers = NamingService.getPublishes();
Set doms = NamingService.getDomsSubscribed();
+ doms.addAll(publishers);
List result = new LinkedList<>();
for (String service : doms) {
result.add(service);
@@ -100,4 +92,8 @@ public class AnsDiscoveryClient implements DiscoveryClient {
return result;
}
+ @Override
+ public ServiceInstance getLocalServiceInstance() {
+ return ansRegistration;
+ }
}
diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClientAutoConfiguration.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClientAutoConfiguration.java
index 7d286976..99118791 100644
--- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClientAutoConfiguration.java
+++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClientAutoConfiguration.java
@@ -19,23 +19,28 @@ package org.springframework.cloud.alicloud.ans;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.alicloud.ans.migrate.MigrateOnConditionMissingClass;
+import org.springframework.cloud.alicloud.ans.registry.AnsRegistration;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
* @author xiaolongzuo
+ * @author pbting
*/
@Configuration
+@Conditional(MigrateOnConditionMissingClass.class)
@ConditionalOnMissingBean(DiscoveryClient.class)
@EnableConfigurationProperties
@AutoConfigureBefore(SimpleDiscoveryClientAutoConfiguration.class)
public class AnsDiscoveryClientAutoConfiguration {
@Bean
- public DiscoveryClient ansDiscoveryClient() {
- return new AnsDiscoveryClient();
+ public DiscoveryClient ansDiscoveryClient(AnsRegistration ansRegistration) {
+ return new AnsDiscoveryClient(ansRegistration);
}
}
diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/endpoint/AnsEndpoint.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/endpoint/AnsEndpoint.java
index 77314748..7a35ef6f 100644
--- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/endpoint/AnsEndpoint.java
+++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/endpoint/AnsEndpoint.java
@@ -16,25 +16,25 @@
package org.springframework.cloud.alicloud.ans.endpoint;
+import com.alibaba.ans.core.NamingService;
+import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
+import org.springframework.cloud.alicloud.context.ans.AnsProperties;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
-import org.springframework.cloud.alicloud.context.ans.AnsProperties;
-
-import com.alibaba.ans.core.NamingService;
-import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host;
-
/**
* @author xiaolongzuo
+ * @author pbting
*/
public class AnsEndpoint extends AbstractEndpoint