")){
+ return "The SSO login status is invalid.Please refresh the browser and log in again!";
+ }
+ }
+
+ Object object = DSSCommonUtils.COMMON_GSON.fromJson(entityString, Object.class);
+ String status = null;
+ String message = null;
+ if (object instanceof Map) {
+ Map map = (Map) object;
+ if (map.get("status") != null) {
+ status = map.get("status").toString();
+ }
+ if (StringUtils.isNotEmpty(status)) {
+ if (null != map.get("message")) {
+ message = map.get("message").toString();
+ }
+ }
+ if ("error".equalsIgnoreCase(status)) {
+ return message;
+ }
+ }
+ return "success";
+ }
+}
diff --git a/dss-appconn/appconns/dss-schedulis-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/schedulis/utils/SchedulisHttpUtils.java b/dss-appconn/appconns/dss-schedulis-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/schedulis/utils/SchedulisHttpUtils.java
new file mode 100644
index 000000000..12cc31e7e
--- /dev/null
+++ b/dss-appconn/appconns/dss-schedulis-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/schedulis/utils/SchedulisHttpUtils.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.schedulis.utils;
+
+import com.webank.wedatasphere.dss.standard.app.sso.Workspace;
+import com.webank.wedatasphere.dss.standard.app.sso.builder.SSOUrlBuilderOperation;
+import com.webank.wedatasphere.dss.standard.app.sso.origin.request.action.DSSGetAction;
+import com.webank.wedatasphere.dss.standard.app.sso.origin.request.action.DSSHttpAction;
+import com.webank.wedatasphere.dss.standard.app.sso.origin.request.action.DSSPostAction;
+import com.webank.wedatasphere.dss.standard.app.sso.request.SSORequestOperation;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationFailedException;
+import com.webank.wedatasphere.dss.standard.sso.utils.SSOHelper;
+import org.apache.linkis.httpclient.request.HttpAction;
+import org.apache.linkis.httpclient.response.HttpResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+import static com.webank.wedatasphere.dss.appconn.schedulis.SchedulisAppConn.SCHEDULIS_APPCONN_NAME;
+
+
+public class SchedulisHttpUtils {
+
+ private final static Logger logger = LoggerFactory.getLogger(SchedulisHttpUtils.class);
+
+ public static SSOUrlBuilderOperation getSSORequestOperation(String url, Workspace workspace) {
+ SSOUrlBuilderOperation ssoUrlBuilderOperation = SSOHelper.createSSOUrlBuilderOperation(workspace);
+ ssoUrlBuilderOperation.setAppName(SCHEDULIS_APPCONN_NAME);
+ ssoUrlBuilderOperation.setReqUrl(url);
+ return ssoUrlBuilderOperation;
+ }
+
+ public static String getHttpResult(String url,
+ DSSHttpAction action,
+ SSORequestOperation
ssoRequestOperation,
+ Workspace workspace) {
+ SSOUrlBuilderOperation ssoUrlBuilderOperation = getSSORequestOperation(url, workspace);
+ action.setUrl(ssoUrlBuilderOperation.getBuiltUrl());
+ HttpResult previewResult = ssoRequestOperation.requestWithSSO(ssoUrlBuilderOperation, action);
+ if (previewResult.getStatusCode() == 200 || previewResult.getStatusCode() == 0) {
+ return previewResult.getResponseBody();
+ } else {
+ logger.error("request Schedulis failed, responseBody is {}.", previewResult.getResponseBody());
+ throw new ExternalOperationFailedException(50063, "request Schedulis failed.");
+ }
+ }
+
+ public static String getHttpGetResult(String url,
+ Map params,
+ SSORequestOperation ssoRequestOperation,
+ Workspace workspace) {
+ DSSGetAction getAction = new DSSGetAction();
+ getAction.getParameters().putAll(params);
+ return getHttpResult(url, getAction, ssoRequestOperation, workspace);
+ }
+
+ public static String getHttpPostResult(String url,
+ Map params,
+ SSORequestOperation ssoRequestOperation,
+ Workspace workspace) {
+ DSSPostAction getAction = new DSSPostAction();
+ getAction.getFormParams().putAll(params);
+ return getHttpResult(url, getAction, ssoRequestOperation, workspace);
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/appconn.properties b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/appconn.properties
new file mode 100644
index 000000000..e1f7094b2
--- /dev/null
+++ b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/appconn.properties
@@ -0,0 +1,20 @@
+#
+# Copyright 2019 WeBank
+# 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.
+#
+#
+
+wds.dss.appconn.scheduler.project.store.dir=/appcom/tmp/wds/scheduler
+
+
+
diff --git a/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/init.sql b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/init.sql
new file mode 100644
index 000000000..7933fe274
--- /dev/null
+++ b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/init.sql
@@ -0,0 +1,19 @@
+-- 适用于第一次安装时
+select @schedulis_appconnId:=id from `dss_appconn` where `appconn_name` = 'schedulis';
+delete from `dss_appconn_instance` where `appconn_id` = @schedulis_appconnId;
+
+delete from dss_appconn where appconn_name = "schedulis";
+INSERT INTO `dss_appconn` (`appconn_name`, `is_user_need_init`, `level`, `if_iframe`, `is_external`, `reference`, `class_name`, `appconn_class_path`, `resource`)
+VALUES ('schedulis', 0, 1, 1, 1, NULL, 'com.webank.wedatasphere.dss.appconn.schedulis.SchedulisAppConn', 'DSS_INSTALL_HOME_VAL/dss-appconns/schedulis', '');
+
+select @schedulis_appconnId:=id from `dss_appconn` where `appconn_name` = 'schedulis';
+
+insert into `dss_appconn_instance` (`appconn_id`, `label`, `url`, `enhance_json`, `homepage_uri`)
+values(@schedulis_appconnId,'DEV','http://APPCONN_INSTALL_IP:APPCONN_INSTALL_PORT/','','');
+
+-- 看appconn组件是要归属于哪个菜单
+select @schedulis_menuId:=id from dss_workspace_menu where name = "生产运维";
+
+delete from dss_workspace_menu_appconn where title_en = "Schedulis";
+INSERT INTO `dss_workspace_menu_appconn` (`appconn_id`, `menu_id`, `title_en`, `title_cn`, `desc_en`, `desc_cn`, `labels_en`, `labels_cn`, `is_active`, `access_button_en`, `access_button_cn`, `manual_button_en`, `manual_button_cn`, `manual_button_url`, `icon`, `order`, `create_by`, `create_time`, `last_update_time`, `last_update_user`, `image`)
+VALUES(@schedulis_appconnId, @schedulis_menuId,'Schedulis','Schedulis','empty desc','empty desc','scheduling, workflow','调度,工作流','1','enter Schedulis','进入Schedulis','user manual','用户手册','manual_url','diaoduxitong-logo',NULL,NULL,NULL,NULL,NULL,'diaoduxitong-icon');
diff --git a/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j.properties b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j.properties
new file mode 100644
index 000000000..ee8619595
--- /dev/null
+++ b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j.properties
@@ -0,0 +1,36 @@
+#
+# Copyright 2019 WeBank
+# 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.
+#
+#
+
+### set log levels ###
+
+log4j.rootCategory=INFO,console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=INFO
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+#log4j.appender.console.layout.ConversionPattern= %d{ISO8601} %-5p (%t) [%F:%M(%L)] - %m%n
+log4j.appender.console.layout.ConversionPattern= %d{ISO8601} %-5p (%t) %p %c{1} - %m%n
+
+
+log4j.appender.com.webank.bdp.ide.core=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.com.webank.bdp.ide.core.Threshold=INFO
+log4j.additivity.com.webank.bdp.ide.core=false
+log4j.appender.com.webank.bdp.ide.core.layout=org.apache.log4j.PatternLayout
+log4j.appender.com.webank.bdp.ide.core.Append=true
+log4j.appender.com.webank.bdp.ide.core.File=logs/linkis.log
+log4j.appender.com.webank.bdp.ide.core.layout.ConversionPattern= %d{ISO8601} %-5p (%t) [%F:%M(%L)] - %m%n
+
+log4j.logger.org.springframework=INFO
diff --git a/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j2.xml b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j2.xml
new file mode 100644
index 000000000..8c40a73e8
--- /dev/null
+++ b/dss-appconn/appconns/dss-schedulis-appconn/src/main/resources/log4j2.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/pom.xml b/dss-appconn/appconns/dss-scriptis-appconn/pom.xml
new file mode 100644
index 000000000..d4f7feac3
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/pom.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+ dss
+ com.webank.wedatasphere.dss
+ 1.1.0
+ ../../../pom.xml
+
+ 4.0.0
+
+ dss-scriptis-appconn
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.3
+ false
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+ false
+ out
+ false
+ false
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/assembly/distribution.xml b/dss-appconn/appconns/dss-scriptis-appconn/src/main/assembly/distribution.xml
new file mode 100644
index 000000000..94b137259
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/assembly/distribution.xml
@@ -0,0 +1,50 @@
+
+
+
+ dss-scriptis-appconn
+
+ dir
+
+ true
+ scriptis
+
+
+
+ ${basedir}/src/main/resources
+
+ init.sql
+
+ 0777
+ db
+
+
+
+ ${basedir}/src/main/icons
+
+ *
+
+ 0777
+ icons
+
+
+
+
+
+
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/connector.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/connector.icon
new file mode 100644
index 000000000..ea7c69e77
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/connector.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/hql.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/hql.icon
new file mode 100644
index 000000000..fc85faf66
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/hql.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/jdbc.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/jdbc.icon
new file mode 100644
index 000000000..31270ec8b
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/jdbc.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/pyspark.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/pyspark.icon
new file mode 100644
index 000000000..abdabfc01
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/pyspark.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/python.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/python.icon
new file mode 100644
index 000000000..ed1ed43f6
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/python.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/scala.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/scala.icon
new file mode 100644
index 000000000..3b25b493c
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/scala.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/shell.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/shell.icon
new file mode 100644
index 000000000..954da701b
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/shell.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/sql.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/sql.icon
new file mode 100644
index 000000000..db6069052
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/sql.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/subFlow.icon b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/subFlow.icon
new file mode 100644
index 000000000..feae0c4e2
--- /dev/null
+++ b/dss-appconn/appconns/dss-scriptis-appconn/src/main/icons/subFlow.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-scriptis-appconn/src/main/resources/init.sql b/dss-appconn/appconns/dss-scriptis-appconn/src/main/resources/init.sql
new file mode 100644
index 000000000..e69de29bb
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/pom.xml b/dss-appconn/appconns/dss-sendemail-appconn/pom.xml
new file mode 100644
index 000000000..44db21489
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ dss
+ com.webank.wedatasphere.dss
+ 1.1.0
+ ../../pom.xml
+
+ 4.0.0
+
+ dss-sendemail-appconn
+ pom
+
+
+ sendemail-appconn-core
+
+
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/pom.xml b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/pom.xml
new file mode 100644
index 000000000..163369494
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/pom.xml
@@ -0,0 +1,153 @@
+
+
+
+
+
+ dss
+ com.webank.wedatasphere.dss
+ 1.1.0
+ ../pom.xml
+
+ 4.0.0
+
+ dss-sendemail-appconn-core
+
+
+ com.webank.wedatasphere.dss
+ dss-appconn-core
+ ${dss.version}
+ compile
+
+
+
+ com.webank.wedatasphere.dss
+ dss-common
+ ${dss.version}
+ compile
+
+
+
+ com.webank.wedatasphere.dss
+ dss-development-process-standard-execution
+ ${dss.version}
+
+
+
+ org.apache.linkis
+ linkis-storage
+ ${linkis.version}
+ provided
+ true
+
+
+
+ org.apache.linkis
+ linkis-module
+ ${linkis.version}
+ provided
+ true
+
+
+
+ org.springframework
+ spring-context-support
+ 5.2.5.RELEASE
+
+
+ javax.mail
+ mail
+ 1.4
+
+
+
+ org.apache.linkis
+ linkis-cs-client
+ ${linkis.version}
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.4
+ compile
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.3
+ false
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+ false
+ out
+ false
+ false
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+
+ src/main/java
+
+ **/*.xml
+
+
+
+ src/main/resources
+
+ **/*.properties
+ **/application.yml
+ **/bootstrap.yml
+ **/log4j2.xml
+
+
+
+
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/assembly/distribution.xml b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/assembly/distribution.xml
new file mode 100644
index 000000000..2519296b9
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/assembly/distribution.xml
@@ -0,0 +1,82 @@
+
+
+
+ dss-sendemail-appconn
+
+ dir
+
+ true
+ sendemail
+
+
+
+
+
+ lib
+ true
+ true
+ false
+ true
+ true
+
+
+
+
+
+ ${basedir}/src/main/resources
+
+ appconn.properties
+
+ 0777
+ /
+ unix
+
+
+
+ ${basedir}/src/main/resources
+
+ *
+
+ 0777
+ conf
+ unix
+
+
+ ${basedir}/src/main/icons
+
+ *
+
+ 0777
+ icons
+
+
+
+ ${basedir}/src/main/resources
+
+ init.sql
+
+ 0777
+ db
+
+
+
+
+
+
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/icons/sendemail.icon b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/icons/sendemail.icon
new file mode 100644
index 000000000..208519eeb
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/icons/sendemail.icon
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/EmailDevelopmentIntegrationStandard.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/EmailDevelopmentIntegrationStandard.java
new file mode 100644
index 000000000..a615c60fb
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/EmailDevelopmentIntegrationStandard.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.service.EmailExecutionService;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefExecutionOperation;
+import com.webank.wedatasphere.dss.standard.app.development.service.*;
+import com.webank.wedatasphere.dss.standard.app.development.standard.OnlyExecutionDevelopmentStandard;
+
+/**
+ * @author allenlliu
+ * @date 2021/10/27 11:34
+ */
+public class EmailDevelopmentIntegrationStandard extends OnlyExecutionDevelopmentStandard {
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ protected RefExecutionService createRefExecutionService() {
+ return new EmailExecutionService();
+ }
+
+ @Override
+ public void init() {
+
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailAppConn.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailAppConn.java
new file mode 100644
index 000000000..a44cbf7d2
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailAppConn.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail;
+
+import com.webank.wedatasphere.dss.appconn.core.ext.OnlyDevelopmentAppConn;
+import com.webank.wedatasphere.dss.appconn.core.impl.AbstractAppConn;
+import com.webank.wedatasphere.dss.standard.app.development.service.AbstractRefExecutionService;
+import com.webank.wedatasphere.dss.standard.app.development.service.RefExecutionService;
+import com.webank.wedatasphere.dss.standard.app.development.standard.DevelopmentIntegrationStandard;
+import com.webank.wedatasphere.dss.standard.app.development.standard.OnlyExecutionDevelopmentStandard;
+
+public class SendEmailAppConn extends AbstractAppConn implements OnlyDevelopmentAppConn {
+
+ private EmailDevelopmentIntegrationStandard standard;
+
+ @Override
+ protected void initialize() {
+ standard = new EmailDevelopmentIntegrationStandard();
+ }
+
+ @Override
+ public DevelopmentIntegrationStandard getOrCreateDevelopmentStandard() {
+ return standard;
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnInstanceConfiguration.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnInstanceConfiguration.java
new file mode 100644
index 000000000..6194f30a3
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnInstanceConfiguration.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.conf;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.EmailGenerator;
+import com.webank.wedatasphere.dss.appconn.sendemail.email.EmailSender;
+import com.webank.wedatasphere.dss.appconn.sendemail.email.generate.MultiContentEmailGenerator;
+import com.webank.wedatasphere.dss.appconn.sendemail.email.sender.SpringJavaEmailSender;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContentGenerator;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContentParser;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.generator.MultiEmailContentGenerator;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser.FileEmailContentParser$;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser.HtmlEmailContentParser$;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser.PictureEmailContentParser$;
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser.TableEmailContentParser$;
+import com.webank.wedatasphere.dss.appconn.sendemail.hook.SendEmailRefExecutionHook;
+import com.webank.wedatasphere.dss.standard.common.utils.AppStandardClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class SendEmailAppConnInstanceConfiguration {
+
+ private static final Logger logger = LoggerFactory.getLogger(SendEmailAppConnInstanceConfiguration.class);
+
+ private static final EmailGenerator EMAIL_GENERATOR = new MultiContentEmailGenerator();
+
+ private static final EmailSender EMAIL_SENDER = createEmailSender();
+
+ private static final EmailContentGenerator[] EMAIL_CONTENT_GENERATOR = createEmailContentGenerators();
+
+ private static final EmailContentParser[] emailContentParsers = createEmailContentParsers();
+
+ private static final SendEmailRefExecutionHook[] sendEmailRefExecutionHooks = createSendEmailRefExecutionHooks();
+
+ private static EmailSender createEmailSender() {
+ String emailSenderClassName = SendEmailAppConnConfiguration.EMAIL_SENDER_CLASS().getValue();
+ try {
+ logger.info("Use user config EmailSender by conf:{}", emailSenderClassName);
+ return (EmailSender)SendEmailAppConnInstanceConfiguration.class.getClassLoader().loadClass(emailSenderClassName).newInstance();
+ } catch (Exception e) {
+ logger.warn("{} can not be instanced, use SpringJavaEmailSender by default.", emailSenderClassName, e);
+ return new SpringJavaEmailSender();
+ }
+ }
+
+ private static EmailContentGenerator[] createEmailContentGenerators() {
+ return new EmailContentGenerator[] {new MultiEmailContentGenerator()};
+ }
+
+ private static EmailContentParser[] createEmailContentParsers() {
+ return new EmailContentParser[] {FileEmailContentParser$.MODULE$,
+ HtmlEmailContentParser$.MODULE$, PictureEmailContentParser$.MODULE$, TableEmailContentParser$.MODULE$};
+ }
+
+ private static SendEmailRefExecutionHook[] createSendEmailRefExecutionHooks() {
+ String hookClasses = SendEmailAppConnConfiguration.EMAIL_HOOK_CLASSES().getValue();
+ logger.info("Use email hook class: {}", hookClasses);
+ return Arrays.stream(hookClasses.split(",")).map(clazz -> {
+ SendEmailRefExecutionHook sendEmailRefExecutionHook = null;
+ try {
+ sendEmailRefExecutionHook = (SendEmailRefExecutionHook)SendEmailAppConnInstanceConfiguration.class.getClassLoader().loadClass(clazz).newInstance();
+ logger.info("Get hook class instance is : {}", sendEmailRefExecutionHook.getClass().getName());
+ } catch (InstantiationException e) {
+ logger.warn("{} can not be instanced", clazz, e);
+ } catch (IllegalAccessException e) {
+ logger.warn("{} can not be instanced", clazz, e);
+ } catch (ClassNotFoundException e) {
+ logger.warn("{} can not be instanced", clazz, e);
+ }
+ return sendEmailRefExecutionHook;
+ }).filter(hook -> null!= hook).toArray(SendEmailRefExecutionHook[]::new);
+ }
+
+ public static EmailSender getEmailSender() {
+ return EMAIL_SENDER;
+ }
+
+ public static void init(){
+ logger.info("init SendEmailAppConnInstanceConfiguration");
+ }
+
+ public static EmailGenerator getEmailGenerator() {
+ return EMAIL_GENERATOR;
+ }
+
+
+ public static EmailContentGenerator[] getEmailContentGenerators() {
+ return EMAIL_CONTENT_GENERATOR;
+ }
+
+ public static EmailContentParser[] getEmailContentParsers() {
+ return emailContentParsers;
+ }
+
+ public static SendEmailRefExecutionHook[] getSendEmailRefExecutionHooks() {
+ return sendEmailRefExecutionHooks;
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/Email.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/Email.java
new file mode 100644
index 000000000..cfd53b8ff
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/Email.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.Attachment;
+
+public interface Email {
+
+ String getContent();
+ void setContent(String content);
+
+ Attachment[] getAttachments();
+ void setAttachments(Attachment[] attachments);
+
+ String getSubject();
+ void setSubject(String subject);
+
+ String getFrom();
+ void setFrom(String from);
+
+ String getTo();
+ void setTo(String to);
+
+ String getCc();
+ void setCc(String cc);
+
+ String getBcc();
+ void setBcc(String bcc);
+
+ String getEmailType();
+ void setEmailType(String emailType);
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/AbstractEmailSender.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/AbstractEmailSender.java
new file mode 100644
index 000000000..71158b690
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/AbstractEmailSender.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.sender;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email;
+import com.webank.wedatasphere.dss.appconn.sendemail.email.EmailSender;
+import org.apache.linkis.common.utils.Utils;
+import scala.runtime.BoxedUnit;
+
+import java.util.Map;
+import java.util.concurrent.Future;
+
+public abstract class AbstractEmailSender implements EmailSender {
+
+ @Override
+ public void init(Map properties) {
+ }
+
+ @Override
+ public Future sendAsync(Email email) {
+ return Utils.defaultScheduler().submit(() -> {
+ send(email);
+ return BoxedUnit.UNIT;
+ });
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/SpringJavaEmailSender.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/SpringJavaEmailSender.java
new file mode 100644
index 000000000..0bc6cf02c
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/email/sender/SpringJavaEmailSender.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.sender;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email;
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.Attachment;
+import com.webank.wedatasphere.dss.appconn.sendemail.exception.EmailSendFailedException;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationFailedException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.linkis.common.conf.CommonVars;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+
+import java.util.Base64;
+import javax.mail.internet.MimeMessage;
+import javax.mail.util.ByteArrayDataSource;
+import java.util.Map;
+import java.util.Properties;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import static com.webank.wedatasphere.dss.appconn.sendemail.conf.SendEmailAppConnConfiguration.*;
+
+public class SpringJavaEmailSender extends AbstractEmailSender {
+
+ private static final Logger logger = LoggerFactory.getLogger(SpringJavaEmailSender.class);
+
+ private JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
+
+ @Override
+ public void init(Map properties) {
+ Properties prop = new Properties();
+ prop.put("mail.smtp.auth", EMAIL_SMTP_AUTH().getValue(properties));
+ prop.put("mail.smtp.starttls.enable", EMAIL_SMTP_STARTTLS_ENABLE().getValue(properties));
+ prop.put("mail.smtp.starttls.required", EMAIL_SMTP_STARTTLS_REQUIRED().getValue(properties));
+ prop.put("mail.smtp.ssl.enable", EMAIL_SMTP_SSL_ENABLED().getValue(properties));
+ prop.put("mail.smtp.timeout", EMAIL_SMTP_TIMEOUT().getValue(properties));
+ javaMailSender.setJavaMailProperties(prop);
+ BiConsumer, CommonVars> setProp = (consumer, c) -> {
+ String value = c.getValue(properties);
+ if(StringUtils.isBlank(value)) {
+ throw new ExternalOperationFailedException(84002, "The value of " + c.key() + " in sendEmail AppConn is null, please set it in appconn.properties of sendEmail AppConn.");
+ } else {
+ consumer.accept(value);
+ }
+ };
+ setProp.accept(javaMailSender::setHost, EMAIL_HOST());
+ javaMailSender.setPort(EMAIL_PORT().getValue(properties));
+ setProp.accept(javaMailSender::setUsername, EMAIL_USERNAME());
+ setProp.accept(javaMailSender::setPassword, EMAIL_PASSWORD());
+ javaMailSender.setProtocol(EMAIL_PROTOCOL().getValue(properties));
+ }
+
+ @Override
+ public void send(Email email) throws EmailSendFailedException {
+ logger.info("Begin to send Email({}).", email.getSubject());
+ try {
+ javaMailSender.send(parseToMimeMessage(email));
+ } catch (Exception e) {
+ logger.error("Send email failed: ", e);
+ EmailSendFailedException ex = new EmailSendFailedException(80001, "Send email failed!");
+ ex.initCause(e);
+ throw ex;
+ }
+ logger.info("Send Email({}) succeed.", email.getSubject());
+ }
+
+ private MimeMessage parseToMimeMessage(Email email) {
+ MimeMessage message = javaMailSender.createMimeMessage();
+ try {
+ MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
+ if (StringUtils.isBlank(javaMailSender.getUsername())) {
+ messageHelper.setFrom(DEFAULT_EMAIL_FROM().getValue());
+ } else {
+ messageHelper.setFrom(javaMailSender.getUsername());
+ }
+ messageHelper.setSubject(email.getSubject());
+ messageHelper.setTo(email.getTo());
+ if (StringUtils.isNotBlank(email.getCc())) {
+ messageHelper.setCc(email.getCc());
+ }
+ if (StringUtils.isNotBlank(email.getBcc())) {
+ messageHelper.setBcc(email.getBcc());
+ }
+ for (Attachment attachment : email.getAttachments()) {
+ messageHelper.addAttachment(attachment.getName(), new ByteArrayDataSource(Base64.getMimeDecoder().decode(attachment.getBase64Str()), attachment.getMediaType()));
+ }
+ messageHelper.setText(email.getContent(), true);
+ } catch (Exception e) {
+ logger.error("Send mail failed", e);
+ }
+ return message;
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContent.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContent.java
new file mode 100644
index 000000000..c69b0d5f0
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent;
+
+public interface EmailContent {
+
+ T getContent();
+
+ void setContent(T content);
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/exception/EmailSendFailedException.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/exception/EmailSendFailedException.java
new file mode 100644
index 000000000..58aebf238
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/exception/EmailSendFailedException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.exception;
+
+
+import org.apache.linkis.common.exception.ErrorException;
+
+public class EmailSendFailedException extends ErrorException {
+ public EmailSendFailedException(int errCode, String desc) {
+ super(errCode, desc);
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/EmailInfo.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/EmailInfo.java
new file mode 100644
index 000000000..7060ac95d
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/EmailInfo.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook;
+
+import java.util.Map;
+
+public class EmailInfo {
+ private String formId;
+ private String user;
+ private String dssProject;
+ private String widgets;
+ private String cc;
+ private String to;
+ private String bcc;
+ private String status;
+ private String priority;
+ private String alertList;
+ private int alertInterval = 60;
+ private String requestCreatedate;
+ private Map widgetColumns;
+
+ public String getFormId() {
+ return formId;
+ }
+
+ public void setFormId(String formId) {
+ this.formId = formId;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getDssProject() {
+ return dssProject;
+ }
+
+ public void setDssProject(String dssProject) {
+ this.dssProject = dssProject;
+ }
+
+ public String getWidgets() {
+ return widgets;
+ }
+
+ public void setWidgets(String widgets) {
+ this.widgets = widgets;
+ }
+
+ public String getCc() {
+ return cc;
+ }
+
+ public void setCc(String cc) {
+ this.cc = cc;
+ }
+
+ public String getTo() {
+ return to;
+ }
+
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ public String getBcc() {
+ return bcc;
+ }
+
+ public void setBcc(String bcc) {
+ this.bcc = bcc;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+ public String getAlertList() {
+ return alertList;
+ }
+
+ public void setAlertList(String alertList) {
+ this.alertList = alertList;
+ }
+
+ public int getAlertInterval() {
+ return alertInterval;
+ }
+
+ public void setAlertInterval(int alertInterval) {
+ this.alertInterval = alertInterval;
+ }
+
+ public String getRequestCreatedate() {
+ return requestCreatedate;
+ }
+
+ public void setRequestCreatedate(String requestCreatedate) {
+ this.requestCreatedate = requestCreatedate;
+ }
+
+ public Map getWidgetColumns() {
+ return widgetColumns;
+ }
+
+ public void setWidgetColumns(Map widgetColumns) {
+ this.widgetColumns = widgetColumns;
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpClientUtil.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpClientUtil.java
new file mode 100644
index 000000000..f2bf89f9d
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpClientUtil.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook;
+
+
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.SocketTimeoutException;
+import java.net.URLEncoder;
+import java.security.cert.CertificateException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@SuppressWarnings("all")
+public final class HttpClientUtil {
+ private final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
+ public final static int connectTimeout = 5000;
+ private static PoolingHttpClientConnectionManager connManager = null;
+ private static CloseableHttpClient httpclient = null;
+
+ private static TrustManager trustAllManager = new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+ }
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+ }
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ };
+
+ static {
+ httpclient = HttpClients.createDefault();
+ }
+
+
+ public static String postForm(String url, int timeout, Map headerMap, List paramsList, String encoding){
+ HttpPost post = new HttpPost(url);
+ try {
+ if(headerMap != null){
+ for(Map.Entry entry : headerMap.entrySet()){
+ post.setHeader(entry.getKey(), entry.getValue().toString());
+ }
+ }
+ //post.setHeader("Content-type", "application/json");
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(timeout)
+ .setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout)
+ .setExpectContinueEnabled(false).build();
+ post.setConfig(requestConfig);
+
+ post.setEntity(new UrlEncodedFormEntity(paramsList, encoding));
+ CloseableHttpResponse response = httpclient.execute(post);
+ try {
+ HttpEntity entity = response.getEntity();
+ try {
+ if(entity != null){
+ String str = EntityUtils.toString(entity, encoding);
+ return str;
+ }
+ } finally {
+ if(entity != null){
+ entity.getContent().close();
+ }
+ }
+ } finally {
+ if(response != null){
+ response.close();
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("invoke http post error!",e);
+ } finally {
+ post.releaseConnection();
+ }
+ return "";
+ }
+
+ public static String postJsonBody(String url, int timeout, Map headerMap,
+ String paraData, String encoding) {
+
+ logger.info("successfully start post Json Body url{} ", url);
+ HttpPost post = new HttpPost(url);
+ try {
+ if (headerMap != null) {
+ for (Map.Entry entry : headerMap.entrySet()) {
+ post.setHeader(entry.getKey(), entry.getValue().toString());
+ }
+ }
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout).setExpectContinueEnabled(false).build();
+ StringEntity jsonEntity = new StringEntity(paraData, ContentType.APPLICATION_JSON);
+ post.setConfig(requestConfig);
+ post.setEntity(jsonEntity);
+ CloseableHttpResponse response = httpclient.execute(post);
+ try {
+ HttpEntity entity = response.getEntity();
+ try {
+ if (entity != null) {
+ String str = EntityUtils.toString(entity, encoding);
+ return str;
+ }
+ } finally {
+ if (entity != null) {
+ entity.getContent().close();
+ }
+ }
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ logger.error("UnsupportedEncodingException", e);
+ throw new RuntimeException("postJsonBody error: "+e.getMessage());
+ } catch (Exception e) {
+ logger.error("Exception", e);
+ throw new RuntimeException("postJsonBody Exception: "+e.getMessage());
+ } finally {
+ post.releaseConnection();
+ }
+ logger.info("successfully end post Json Body url{} ", url);
+ return "";
+ }
+
+ @SuppressWarnings("deprecation")
+ public static String invokeGet(String url, Map params, String encode, int connectTimeout,
+ int soTimeout) {
+ String responseString = null;
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout)
+ .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(url);
+ int i = 0;
+ if (params != null) {
+ for (Map.Entry entry : params.entrySet()) {
+ if (i == 0 && !url.contains("?")) {
+ sb.append("?");
+ } else {
+ sb.append("&");
+ }
+ sb.append(entry.getKey());
+ sb.append("=");
+ String value = entry.getValue();
+ try {
+ sb.append(URLEncoder.encode(value, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ logger.warn("encode http get params error, value is " + value, e);
+ sb.append(URLEncoder.encode(value));
+ }
+ i++;
+ }
+ }
+ HttpGet get = new HttpGet(sb.toString());
+ get.setConfig(requestConfig);
+ try {
+ CloseableHttpResponse response = httpclient.execute(get);
+ try {
+ HttpEntity entity = response.getEntity();
+ try {
+ if (entity != null) {
+ responseString = EntityUtils.toString(entity, encode);
+ }
+ } finally {
+ if (entity != null) {
+ entity.getContent().close();
+ }
+ }
+ } catch (Exception e) {
+ logger.error(String.format("[HttpUtils Get]get response error, url:%s", sb.toString()), e);
+ return responseString;
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ // System.out.println(String.format("[HttpUtils Get]Debug url:%s ,
+ // response string %s:", sb.toString(), responseString));
+ } catch (SocketTimeoutException e) {
+ logger.error(String.format("[HttpUtils Get]invoke get timout error, url:%s", sb.toString()), e);
+ return responseString;
+ } catch (Exception e) {
+ logger.error(String.format("[HttpUtils Get]invoke get error, url:%s", sb.toString()), e);
+ } finally {
+ get.releaseConnection();
+ }
+ return responseString;
+ }
+
+ /**
+ * HTTPS请求,默认超时为5S
+ *
+ * @param reqURL
+ * @param params
+ * @return
+ */
+ public static String connectPostHttps(String reqURL, Map params) {
+
+ String responseContent = null;
+ HttpPost httpPost = new HttpPost(reqURL);
+ try {
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout)
+ .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
+ List formParams = new ArrayList();
+ httpPost.setEntity(new UrlEncodedFormEntity(formParams, Consts.UTF_8));
+ httpPost.setConfig(requestConfig);
+ // 绑定到请求 Entry
+ for (Map.Entry entry : params.entrySet()) {
+ formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+ }
+ CloseableHttpResponse response = httpclient.execute(httpPost);
+ try {
+ // 执行POST请求
+ HttpEntity entity = response.getEntity(); // 获取响应实体
+ try {
+ if (null != entity) {
+ responseContent = EntityUtils.toString(entity, Consts.UTF_8);
+ }
+ } finally {
+ if (entity != null) {
+ entity.getContent().close();
+ }
+ }
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ logger.info("requestURI : " + httpPost.getURI() + ", responseContent: " + responseContent);
+ } catch (ClientProtocolException e) {
+ logger.error("ClientProtocolException", e);
+ } catch (IOException e) {
+ logger.error("IOException", e);
+ } finally {
+ httpPost.releaseConnection();
+ }
+ return responseContent;
+
+ }
+
+ class Test {
+ String v;
+ String k;
+
+ public String getV() {
+ return v;
+ }
+
+ public void setV(String v) {
+ this.v = v;
+ }
+
+ public String getK() {
+ return k;
+ }
+
+ public void setK(String k) {
+ this.k = k;
+ }
+
+ }
+
+ // 随机4位数
+ public static String getRandomValue() {
+ String str = "0123456789";
+ StringBuilder sb = new StringBuilder(4);
+ for (int i = 0; i < 4; i++) {
+ char ch = str.charAt(new Random().nextInt(str.length()));
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+
+ // 当前时间到秒
+ public static String getTimestamp() {
+
+ Date date = new Date();
+ String timestamp = String.valueOf(date.getTime() / 1000);
+ return timestamp;
+ }
+
+ // 当前时间到秒
+ public static String getNowDate() {
+ Date date = new Date();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ return sdf.format(date);
+ }
+
+ public static String postJsonBody2(String url, int timeout, Map headerMap,
+ List paramsList, String encoding) {
+ logger.info("successfully start post Json Body url{} ", url);
+ HttpPost post = new HttpPost(url);
+ try {
+ if (headerMap != null) {
+ for (Map.Entry entry : headerMap.entrySet()) {
+ post.setHeader(entry.getKey(), entry.getValue().toString());
+ }
+ }
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout).setExpectContinueEnabled(false).build();
+ post.setConfig(requestConfig);
+ if (paramsList.size() > 0) {
+ UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramsList, encoding);
+ post.setEntity(entity);
+ }
+ CloseableHttpResponse response = httpclient.execute(post);
+ try {
+ HttpEntity entity = response.getEntity();
+ try {
+ if (entity != null) {
+ String str = EntityUtils.toString(entity, encoding);
+ return str;
+ }
+ } finally {
+ if (entity != null) {
+ entity.getContent().close();
+ }
+ }
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ logger.error("UnsupportedEncodingException", e);
+ throw new RuntimeException("failed post json return blank!");
+ } catch (Exception e) {
+ logger.error("Exception", e);
+ throw new RuntimeException("failed post json return blank!");
+ } finally {
+ post.releaseConnection();
+ }
+ logger.info("successfully end post Json Body url{} ", url);
+ return "";
+ }
+
+ public static String postJsonBody3(String url, int timeout, Map headerMap,
+ Map paramsList, String encoding) {
+ HttpPost post = new HttpPost(url);
+ try {
+ if (headerMap != null) {
+ for (Map.Entry entry : headerMap.entrySet()) {
+ post.setHeader(entry.getKey(), entry.getValue().toString());
+ }
+ }
+ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
+ .setConnectionRequestTimeout(timeout).setExpectContinueEnabled(false).build();
+ post.setConfig(requestConfig);
+ if (paramsList.size() > 0) {
+ //JSONArray jsonArray = JSONArray.fromObject(paramsList);
+ //post.setEntity(new StringEntity(jsonArray.get(0).toString(), encoding));
+ post.setEntity(new StringEntity(null, encoding));
+ //logger.info("successfully start post Json Body url{},params ", url,jsonArray.get(0).toString());
+ logger.info("successfully start post Json Body url{},params ", url,null);
+ }
+ CloseableHttpResponse response = httpclient.execute(post);
+ try {
+ HttpEntity entity = response.getEntity();
+ try {
+ if (entity != null) {
+ String str = EntityUtils.toString(entity, encoding);
+ return str;
+ }
+ } finally {
+ if (entity != null) {
+ entity.getContent().close();
+ }
+ }
+ } finally {
+ if (response != null) {
+ response.close();
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ logger.error("UnsupportedEncodingException", e);
+ throw new RuntimeException("failed post json return blank!");
+ } catch (Exception e) {
+ logger.error("Exception", e);
+ throw new RuntimeException("failed post json return blank!");
+ } finally {
+ post.releaseConnection();
+ }
+ logger.info("successfully end post Json Body url{} ", url);
+ return "";
+ }
+
+ public static String executeGet(String url)
+ {
+ String rtnStr = "";
+ HttpGet httpGet = new HttpGet(url);
+ try {
+ HttpResponse httpResponse = httpclient.execute(httpGet);
+ //获得返回的结果
+ rtnStr = EntityUtils.toString(httpResponse.getEntity());
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ httpGet.releaseConnection();
+ }
+ return rtnStr;
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpResponseModel.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpResponseModel.java
new file mode 100644
index 000000000..a6965b114
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/HttpResponseModel.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook;
+
+public abstract class HttpResponseModel {
+ private String method;
+ private int status;
+ private String message;
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/WidgetMetaData.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/WidgetMetaData.java
new file mode 100644
index 000000000..1e268538f
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/hook/WidgetMetaData.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook;
+
+import java.util.List;
+import java.util.Map;
+
+public class WidgetMetaData extends HttpResponseModel{
+ public static class Meta{
+ private String name;
+ private String updated;
+ private String columns;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUpdated() {
+ return updated;
+ }
+
+ public void setUpdated(String updated) {
+ this.updated = updated;
+ }
+
+ public String getColumns() {
+ return columns;
+ }
+
+ public void setColumns(String columns) {
+ this.columns = columns;
+ }
+ }
+
+
+ public static class Data{
+ private String projectName;
+ private List widgetsMetaData;
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+ public List getWidgetsMetaData() {
+ return widgetsMetaData;
+ }
+
+ public void setWidgetsMetaData(List widgetsMetaData) {
+ this.widgetsMetaData = widgetsMetaData;
+ }
+ }
+
+ private Data data;
+
+ public Data getData() {
+ return data;
+ }
+
+ public void setData(Data data) {
+ this.data = data;
+ }
+}
+
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/service/EmailExecutionService.java b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/service/EmailExecutionService.java
new file mode 100644
index 000000000..6316f4597
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/java/com/webank/wedatasphere/dss/appconn/sendemail/service/EmailExecutionService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.service;
+
+import com.webank.wedatasphere.dss.appconn.sendemail.SendEmailRefExecutionOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefExecutionOperation;
+import com.webank.wedatasphere.dss.standard.app.development.service.AbstractRefExecutionService;
+
+/**
+ * @author allenlliu
+ * @date 2021/10/27 11:39
+ */
+public class EmailExecutionService extends AbstractRefExecutionService {
+
+ @Override
+ public RefExecutionOperation createRefExecutionOperation() {
+ return new SendEmailRefExecutionOperation();
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/appconn.properties b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/appconn.properties
new file mode 100644
index 000000000..30ea40102
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/appconn.properties
@@ -0,0 +1,34 @@
+#
+# /*
+# * Copyright 2019 WeBank
+# *
+# * 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.
+# */
+#
+
+# The following properties must be set in.
+wds.dss.appconn.email.host=
+wds.dss.appconn.email.port=
+# wds.dss.appconn.email.protocol=smtp
+wds.dss.appconn.email.username=
+wds.dss.appconn.email.password=
+
+# The following properties have default value.
+# wds.dss.appconn.email.smtp.auth=true
+# wds.dss.appconn.email.smtp.starttls.enable=true
+# wds.dss.appconn.email.smtp.starttls.required=true
+# wds.dss.appconn.email.smtp.ssl.enable=true
+# wds.dss.appconn.email.smtp.timeout=25000
+
+
+
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/init.sql b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/init.sql
new file mode 100644
index 000000000..75654adc7
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/resources/init.sql
@@ -0,0 +1,51 @@
+-- TODO 这里只适用于第一次安装时。如果是更新的话dss_appconn表不能先删除再插入,因为其他表如dss_workspace_appconn_role关联了appconn_id(不能变),需要使用update、alter语句更新
+select @sendemail_appconnId:=id from `dss_appconn` where `appconn_name` = 'sendemail';
+delete from `dss_appconn_instance` where `appconn_id` = @sendemail_appconnId;
+
+INSERT INTO `dss_appconn` (`appconn_name`, `is_user_need_init`, `level`, `if_iframe`, `is_external`, `reference`, `class_name`, `appconn_class_path`, `resource`)
+VALUES ('sendemail', 0, 1, 1, 1, NULL, 'com.webank.wedatasphere.dss.appconn.sendemail.SendEmailAppConn', 'DSS_INSTALL_HOME_VAL/dss-appconns/sendemail', '');
+
+select @sendemail_appconnId:=id from `dss_appconn` where `appconn_name` = 'sendemail';
+
+INSERT INTO `dss_appconn_instance` (`appconn_id`, `label`, `url`, `enhance_json`, `homepage_uri`)
+VALUES (@sendemail_appconnId, 'DEV', 'sendemail', '{"email.host":"EMAIL_HOST","email.port":"EMAIL_PORT","email.username":"EMAIL_USERNAME","email.password":"EMAIL_PASSWORD","email.protocol":"EMAIL_PROTOCOL"}', '');
+
+delete from dss_workflow_node where name = "sendemail";
+insert into `dss_workflow_node` (`name`, `appconn_name`, `node_type`, `jump_type`, `support_jump`, `submit_to_scheduler`, `enable_copy`, `should_creation_before_node`, `icon_path`)
+values('sendemail','sendemail','linkis.appconn.sendemail','0','0','1','1','0','icons/sendemail.icon');
+
+select @sendemail_nodeId:=id from `dss_workflow_node` where `node_type` = 'linkis.appconn.sendemail';
+
+delete from `dss_workflow_node_to_group` where `node_id`=@sendemail_nodeId;
+
+delete from `dss_workflow_node_to_ui` where `workflow_node_id`=@sendemail_nodeId;
+
+-- 查找节点所属组的id
+select @sendemail_node_groupId:=id from `dss_workflow_node_group` where `name` = '数据输出';
+
+INSERT INTO `dss_workflow_node_to_group`(`node_id`,`group_id`) values (@sendemail_nodeId, @sendemail_node_groupId);
+
+-- 考虑表中有的是重复记录,最好加上limit 1
+select @sendemail_node_ui_lable_name_1:=id from `dss_workflow_node_ui` where `lable_name` = '节点名' limit 1;
+select @sendemail_node_ui_lable_name_2:=id from `dss_workflow_node_ui` where `lable_name` = '节点描述' limit 1;
+select @sendemail_node_ui_lable_name_3:=id from `dss_workflow_node_ui` where `lable_name` = '业务标签' limit 1;
+select @sendemail_node_ui_lable_name_4:=id from `dss_workflow_node_ui` where `lable_name` = '应用标签' limit 1;
+select @sendemail_node_ui_lable_name_5:=id from `dss_workflow_node_ui` where `lable_name` = '是否复用引擎' limit 1;
+select @sendemail_node_ui_lable_name_6:=id from `dss_workflow_node_ui` where `lable_name` = '类型' limit 1;
+select @sendemail_node_ui_lable_name_7:=id from `dss_workflow_node_ui` where `lable_name` = '邮件标题' limit 1;
+select @sendemail_node_ui_lable_name_8:=id from `dss_workflow_node_ui` where `lable_name` = '收件人' limit 1;
+select @sendemail_node_ui_lable_name_9:=id from `dss_workflow_node_ui` where `lable_name` = '抄送' limit 1;
+select @sendemail_node_ui_lable_name_10:=id from `dss_workflow_node_ui` where `lable_name` = '秘密抄送' limit 1;
+select @sendemail_node_ui_lable_name_11:=id from `dss_workflow_node_ui` where `lable_name` = '发送项' limit 1;
+
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_1);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_2);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_3);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_4);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_5);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_6);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_7);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_8);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_9);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_10);
+INSERT INTO `dss_workflow_node_to_ui`(`workflow_node_id`,`ui_id`) values (@sendemail_nodeId, @sendemail_node_ui_lable_name_11);
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailRefExecutionOperation.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailRefExecutionOperation.scala
new file mode 100644
index 000000000..d4cae247a
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/SendEmailRefExecutionOperation.scala
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail
+
+import java.util
+
+import com.webank.wedatasphere.dss.appconn.sendemail.conf.SendEmailAppConnInstanceConfiguration
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.ExecutionResponseRef.ExecutionResponseRefBuilder
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.{ExecutionResponseRef, RefExecutionRequestRef}
+import com.webank.wedatasphere.dss.standard.app.development.operation.{AbstractDevelopmentOperation, RefExecutionOperation}
+import com.webank.wedatasphere.dss.standard.common.entity.ref.ResponseRef
+import org.apache.linkis.common.utils.Utils
+
+import scala.collection.JavaConversions._
+
+class SendEmailRefExecutionOperation
+ extends AbstractDevelopmentOperation[RefExecutionRequestRef.RefExecutionRequestRefImpl, ResponseRef]
+ with RefExecutionOperation[RefExecutionRequestRef.RefExecutionRequestRefImpl] {
+
+ private val sendEmailAppConnHooks = SendEmailAppConnInstanceConfiguration.getSendEmailRefExecutionHooks
+ private val emailContentParsers = SendEmailAppConnInstanceConfiguration.getEmailContentParsers
+ private val emailContentGenerators = SendEmailAppConnInstanceConfiguration.getEmailContentGenerators
+ private val emailGenerator = SendEmailAppConnInstanceConfiguration.getEmailGenerator
+ private val emailSender = SendEmailAppConnInstanceConfiguration.getEmailSender
+
+
+ override def init(): Unit = {
+ super.init()
+ val properties = new util.HashMap[String, String]
+ service.getAppInstance.getConfig.foreach {
+ case (key: String, value: Object) if value != null =>
+ properties.put(key, value.toString)
+ case _ =>
+ }
+ emailSender.init(properties)
+ }
+
+ override def execute(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): ExecutionResponseRef = {
+ val email = Utils.tryCatch {
+ sendEmailAppConnHooks.foreach(_.preGenerate(requestRef))
+ val email = emailGenerator.generateEmail(requestRef)
+ emailContentParsers.foreach{
+ p => Utils.tryQuietly(p.parse(email))
+ }
+ emailContentGenerators.foreach{
+ g => Utils.tryQuietly(g.generate(email))
+ }
+ sendEmailAppConnHooks.foreach(_.preSend(requestRef, email))
+ email
+ }{ t =>
+ return putErrorMsg("解析邮件内容失败!", t)
+ }
+ Utils.tryCatch {
+ emailSender.send(email)
+ new ExecutionResponseRefBuilder().success()
+ }(putErrorMsg("发送邮件失败!", _))
+ }
+
+ protected def putErrorMsg(errorMsg: String, t: Throwable): ExecutionResponseRef = {
+ logger.error(s"failed to send email, $errorMsg ", t)
+ new ExecutionResponseRefBuilder().setException(t).setErrorMsg(errorMsg).error()
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnConfiguration.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnConfiguration.scala
new file mode 100644
index 000000000..cdd2f3728
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/conf/SendEmailAppConnConfiguration.scala
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.conf
+
+import org.apache.linkis.common.conf.CommonVars
+
+object SendEmailAppConnConfiguration {
+
+ val EMAIL_SENDER_CLASS = CommonVars("wds.dss.appconn.email.sender.class",
+ "com.webank.wedatasphere.dss.appconn.sendemail.email.sender.EsbEmailSender")
+
+ val EMAIL_HOOK_CLASSES = CommonVars("wds.dss.appconn.email.hook.classes",
+ "com.webank.wedatasphere.dss.appconn.sendemail.hook.SendEmailItsmCheckHook," +
+ "com.webank.wedatasphere.dss.appconn.sendemail.hook.SendEmailVisualisContentLimitHook," +
+ "com.webank.wedatasphere.dss.appconn.sendemail.hook.SendEmailTableauCheckHook")
+
+ val EMAIL_IMAGE_HEIGHT = CommonVars("wds.dss.appconn.email.image.height", 500)
+ val EMAIL_IMAGE_WIDTH = CommonVars("wds.dss.appconn.email.image.width", 1920)
+ val DEFAULT_EMAIL_FROM = CommonVars("wds.dss.appconn.email.from.default", "")
+ val DEFAULT_EMAIL_SUFFIX = CommonVars("wds.dss.appconn.email.suffix.default", "@webank.com")
+
+ val EMAIL_HOST = CommonVars("wds.dss.appconn.email.host", "")
+ val EMAIL_PORT: CommonVars[Integer] = CommonVars[Integer]("wds.dss.appconn.email.port", -1)
+ val EMAIL_PROTOCOL = CommonVars("wds.dss.appconn.email.protocol", "smtp")
+ val EMAIL_USERNAME = CommonVars("wds.dss.appconn.email.username", "")
+ val EMAIL_PASSWORD = CommonVars("wds.dss.appconn.email.password", "")
+
+ val EMAIL_SMTP_AUTH = CommonVars("wds.dss.appconn.email.smtp.auth", "true")
+ val EMAIL_SMTP_STARTTLS_ENABLE = CommonVars("wds.dss.appconn.email.smtp.starttls.enable", "true")
+ val EMAIL_SMTP_STARTTLS_REQUIRED = CommonVars("wds.dss.appconn.email.smtp.starttls.required", "true")
+ val EMAIL_SMTP_SSL_ENABLED = CommonVars("wds.dss.appconn.email.smtp.ssl.enable", "true")
+ val EMAIL_SMTP_TIMEOUT: CommonVars[Integer] = CommonVars("wds.dss.appconn.email.smtp.timeout", 25000)
+
+ val EMAIL_ENTITY_CLASSES = CommonVars("wds.dss.appconn.email.hook.entity.classes","com.webank.wedatasphere.dss.appconn.sendemail.hook.entity.newvisualis.NewVisualisEmailInfo," +
+ "com.webank.wedatasphere.dss.appconn.sendemail.hook.entity.visualis.VisualisEmailInfo")
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/cs/EmailCSHelper.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/cs/EmailCSHelper.scala
new file mode 100644
index 000000000..674e133b0
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/cs/EmailCSHelper.scala
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.cs
+
+
+import java.util
+
+import com.google.gson.internal.LinkedTreeMap
+import com.webank.wedatasphere.dss.appconn.sendemail.exception.EmailSendFailedException
+import com.webank.wedatasphere.dss.standard.app.development.listener.core.ExecutionRequestRefContext
+import org.apache.linkis.common.utils.Logging
+import org.apache.linkis.cs.client.service.LinkisJobDataServiceImpl
+import org.apache.linkis.cs.client.utils.{ContextServiceUtils, SerializeHelper}
+import org.apache.linkis.cs.common.entity.enumeration.{ContextScope, ContextType}
+import org.apache.linkis.cs.common.entity.source.CommonContextKey
+import org.apache.linkis.cs.common.utils.CSCommonUtils
+import org.apache.linkis.server.JSONUtils
+import org.springframework.util.CollectionUtils
+
+import scala.collection.JavaConversions._
+
+
+object EmailCSHelper extends Logging{
+
+ /**
+ * update by peaceWong form cs to get job ID
+ */
+ def getJobIds(refContext: ExecutionRequestRefContext): Array[Long] = {
+ val contextIDStr = ContextServiceUtils.getContextIDStrByMap(refContext.getRuntimeMap)
+ val nodeIDs = refContext.getRuntimeMap.get("content") match {
+ case string: String => JSONUtils.gson.fromJson(string, classOf[java.util.List[String]])
+ case list: java.util.List[String] => list
+ }
+ if (null == nodeIDs || nodeIDs.length < 1){
+ throw new EmailSendFailedException(80003 ,"empty result set is not allowed")
+ }
+ info(s"From cs to getJob ids $nodeIDs.")
+ val jobIds = nodeIDs.map(ContextServiceUtils.getNodeNameByNodeID(contextIDStr, _)).map{ nodeName =>
+ val contextKey = new CommonContextKey
+ contextKey.setContextScope(ContextScope.PUBLIC)
+ contextKey.setContextType(ContextType.DATA)
+ contextKey.setKey(CSCommonUtils.NODE_PREFIX + nodeName + CSCommonUtils.JOB_ID)
+ LinkisJobDataServiceImpl.getInstance().getLinkisJobData(contextIDStr, SerializeHelper.serializeContextKey(contextKey))
+ }.map(_.getJobID).toArray
+ if (null == jobIds || jobIds.length < 1){
+ throw new EmailSendFailedException(80003 ,"empty result set is not allowed")
+ }
+ info(s"Job IDs is ${jobIds.toList}.")
+ jobIds
+ }
+
+ def getJobTypes(refContext: ExecutionRequestRefContext):util.ArrayList[String] = {
+ val jobTypes = new util.ArrayList[String]()
+ getJobIds(refContext).foreach { jobId =>
+ jobTypes.add(refContext.fetchLinkisJob(jobId).getParams.get("labels").asInstanceOf[LinkedTreeMap[_,_]].get("codeType").toString)
+ }
+ if (CollectionUtils.isEmpty(jobTypes)) {
+ throw new EmailSendFailedException(80003 ,"empty result set is not allowed")
+ }
+ info(s"Job Types is $jobTypes.")
+ jobTypes
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailGenerator.scala
new file mode 100644
index 000000000..32c24529e
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailGenerator.scala
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email
+
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.RefExecutionRequestRef
+
+trait EmailGenerator {
+
+ def generateEmail(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): Email
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailSender.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailSender.scala
new file mode 100644
index 000000000..7531466e9
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/EmailSender.scala
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email
+
+import java.util
+import java.util.concurrent.Future
+
+import com.webank.wedatasphere.dss.appconn.sendemail.exception.EmailSendFailedException
+
+trait EmailSender {
+
+ def init(properties: util.Map[String, String]): Unit
+
+ @throws(classOf[EmailSendFailedException])
+ def send(email: Email): Unit
+
+ def sendAsync(email: Email): Future[Unit]
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/AbstractEmail.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/AbstractEmail.scala
new file mode 100644
index 000000000..3ef44dfe3
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/AbstractEmail.scala
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.domain
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+
+import scala.collection.mutable.ArrayBuffer
+
+class AbstractEmail extends Email {
+
+ private var content: String = _
+ private var attachments = ArrayBuffer[Attachment]()
+ private var subject: String = _
+ private var from: String = _
+ private var to: String = _
+ private var cc: String = _
+ private var bcc: String = _
+ private var emialType: String = _
+
+ override def getContent: String = content
+ override def setContent(content: String): Unit = this.content = content
+
+ override def getAttachments: Array[Attachment] = attachments.toArray
+ override def setAttachments(attachments: Array[Attachment]): Unit =
+ this.attachments ++= attachments
+ def addAttachment(attachment: Attachment): Unit = this.attachments += attachment
+
+ override def getSubject: String = subject
+ override def setSubject(subject: String): Unit = this.subject = subject
+
+ override def getFrom: String = from
+ override def setFrom(from: String): Unit = this.from = from
+
+ override def getTo: String = to
+ override def setTo(to: String): Unit = this.to = to
+
+ override def getCc: String = cc
+ override def setCc(cc: String): Unit = this.cc = cc
+
+ override def getBcc: String = bcc
+ override def setBcc(bcc: String): Unit = this.bcc = bcc
+
+ override def getEmailType: String = emialType
+ override def setEmailType(emailType: String): Unit = this.emialType = emailType
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/Attachment.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/Attachment.scala
new file mode 100644
index 000000000..dbea0da83
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/Attachment.scala
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.domain
+
+import java.io.File
+
+trait Attachment {
+ def getName: String
+ def getBase64Str: String
+ def getFile: File
+ def getMediaType: String
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/MultiContentEmail.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/MultiContentEmail.scala
new file mode 100644
index 000000000..086488106
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/MultiContentEmail.scala
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.domain
+
+import java.util
+
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContent
+
+import scala.collection.JavaConversions._
+
+class MultiContentEmail extends AbstractEmail {
+
+ private val emailContents = new util.ArrayList[EmailContent[_]]()
+
+ def addEmailContent(emailContent: EmailContent[_]): Unit = emailContents.add(emailContent)
+
+ def getEmailContents: Array[EmailContent[_]] = emailContents.toIterator.toArray
+
+
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/PngAttachment.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/PngAttachment.scala
new file mode 100644
index 000000000..369a55cb0
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/domain/PngAttachment.scala
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.domain
+
+import java.io.File
+
+class PngAttachment(name: String, b64: String) extends Attachment {
+
+ override def getName: String = name
+
+ override def getBase64Str: String = b64
+
+ override def getFile: File = null //TODO write b64 to file
+
+ override def getMediaType: String = "image/png"
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/AbstractEmailGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/AbstractEmailGenerator.scala
new file mode 100644
index 000000000..556303371
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/AbstractEmailGenerator.scala
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.generate
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.AbstractEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.email.{Email, EmailGenerator}
+import com.webank.wedatasphere.dss.common.utils.VariableUtils
+import com.webank.wedatasphere.dss.standard.app.development.listener.core.ExecutionRequestRefContext
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.RefExecutionRequestRef
+import org.apache.linkis.common.utils.Logging
+
+trait AbstractEmailGenerator extends EmailGenerator with Logging{
+
+ protected def createEmail(): AbstractEmail
+
+ override def generateEmail(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): Email = {
+ val email = createEmail()
+ generateEmailInfo(requestRef, email)
+ generateEmailContent(requestRef, email)
+ email
+ }
+
+ protected def getRuntimeMap(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): java.util.Map[String, AnyRef] =
+ requestRef.getExecutionRequestRefContext.getRuntimeMap
+
+ protected def getExecutionRequestRefContext(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): ExecutionRequestRefContext =
+ requestRef.getExecutionRequestRefContext
+
+ protected def generateEmailInfo(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl, email: AbstractEmail): Unit = {
+ import scala.collection.JavaConversions._
+ val runtimeMap = getRuntimeMap(requestRef)
+ runtimeMap foreach {
+ case (k, v) => logger.info(s"K is $k, V is $v")
+ }
+ val subject = if (runtimeMap.get("subject") != null) {
+ VariableUtils.replace(runtimeMap.get("subject").toString)
+ } else{
+ "This is an email"
+ }
+ email.setSubject(subject)
+ val bcc = if (runtimeMap.get("bcc") != null) runtimeMap.get("bcc").toString else ""
+ email.setBcc(bcc)
+ val cc = if (runtimeMap.get("cc") != null) runtimeMap.get("cc").toString else ""
+ email.setCc(cc)
+ val from = if (runtimeMap.get("from") != null) runtimeMap.get("from").toString else
+ if(runtimeMap.get("wds.dss.workflow.submit.user") != null){
+ runtimeMap.get("wds.dss.workflow.submit.user").toString
+ } else runtimeMap.get("user").toString
+ email.setFrom(from)
+ val to = if (runtimeMap.get("to") != null) runtimeMap.get("to").toString else ""
+ email.setTo(to)
+ }
+
+ protected def generateEmailContent(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl, email: AbstractEmail): Unit
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/MultiContentEmailGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/MultiContentEmailGenerator.scala
new file mode 100644
index 000000000..7043d54d5
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/email/generate/MultiContentEmailGenerator.scala
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.email.generate
+
+import com.google.gson.internal.LinkedTreeMap
+import com.webank.wedatasphere.dss.appconn.sendemail.cs.EmailCSHelper
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.{AbstractEmail, MultiContentEmail}
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.PictureEmailContent
+import com.webank.wedatasphere.dss.appconn.sendemail.exception.EmailSendFailedException
+import com.webank.wedatasphere.dss.common.utils.DSSCommonUtils
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.RefExecutionRequestRef
+import org.apache.commons.lang3.StringUtils
+import org.apache.linkis.storage.resultset.ResultSetFactory
+
+class MultiContentEmailGenerator extends AbstractEmailGenerator {
+
+ override protected def createEmail(): AbstractEmail = new MultiContentEmail
+
+ override protected def generateEmailContent(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl, email: AbstractEmail): Unit = email match {
+ case multiContentEmail: MultiContentEmail =>
+ val runtimeMap = getRuntimeMap(requestRef)
+ val refContext = getExecutionRequestRefContext(requestRef)
+ runtimeMap.get("category") match {
+ case "node" =>
+ val resultSetFactory = ResultSetFactory.getInstance
+ EmailCSHelper.getJobIds(refContext).foreach { jobId =>
+ refContext.fetchLinkisJobResultSetPaths(jobId).foreach { fsPath =>
+ val resultSet = resultSetFactory.getResultSetByPath(fsPath)
+ val emailContent = resultSet.resultSetType() match {
+ case ResultSetFactory.PICTURE_TYPE => new PictureEmailContent(fsPath)
+ case ResultSetFactory.HTML_TYPE => throw new EmailSendFailedException(80003 ,"html result set is not allowed")//new HtmlEmailContent(fsPath)
+ case ResultSetFactory.TABLE_TYPE => throw new EmailSendFailedException(80003 ,"table result set is not allowed")//new TableEmailContent(fsPath)
+ case ResultSetFactory.TEXT_TYPE => throw new EmailSendFailedException(80003 ,"text result set is not allowed")//new FileEmailContent(fsPath)
+ }
+ multiContentEmail.addEmailContent(emailContent)
+ }
+ if (StringUtils.isBlank(multiContentEmail.getEmailType)) {
+ val emailType = refContext.fetchLinkisJob(jobId).getParams.get("labels").asInstanceOf[LinkedTreeMap[_,_]].get("codeType").toString
+ multiContentEmail.setEmailType(emailType)
+ }
+ }
+ case "file" => throw new EmailSendFailedException(80003 ,"file content is not allowed") //addContentEmail(c => new FileEmailContent(new FsPath(c)))
+ case "text" => throw new EmailSendFailedException(80003 ,"text content is not allowed")//addContentEmail(new TextEmailContent(_))
+ case "link" => throw new EmailSendFailedException(80003 ,"link content is not allowed")//addContentEmail(new UrlEmailContent(_))
+ }
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentGenerator.scala
new file mode 100644
index 000000000..a6235abd2
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentGenerator.scala
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+
+trait EmailContentGenerator {
+
+ def generate(email: Email): Unit
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentParser.scala
new file mode 100644
index 000000000..a85d52269
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/EmailContentParser.scala
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+
+trait EmailContentParser {
+
+ def parse(email: Email): Unit
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/ArrayEmailContent.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/ArrayEmailContent.scala
new file mode 100644
index 000000000..2fc552dd8
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/ArrayEmailContent.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain
+
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContent
+
+class ArrayEmailContent extends EmailContent[Array[String]] {
+
+ private var content: Array[String] = _
+
+ override def getContent: Array[String] = content
+
+ override def setContent(content: Array[String]): Unit = this.content = content
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/FsPathStoreEmailContent.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/FsPathStoreEmailContent.scala
new file mode 100644
index 000000000..ebbe876fc
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/FsPathStoreEmailContent.scala
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain
+
+import org.apache.linkis.common.io.FsPath
+
+trait FsPathStoreEmailContent {
+ private var fsPath: FsPath = _
+
+ def getFsPath: FsPath = fsPath
+ def setFsPath(fsPath: FsPath): Unit = this.fsPath = fsPath
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/StringEmailContent.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/StringEmailContent.scala
new file mode 100644
index 000000000..e28ab0bc8
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/StringEmailContent.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain
+
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContent
+
+class StringEmailContent extends EmailContent[String] {
+
+ private var content: String = _
+
+ override def getContent: String = content
+
+ override def setContent(content: String): Unit = this.content = content
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/package.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/package.scala
new file mode 100644
index 000000000..016398556
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/domain/package.scala
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain
+
+import org.apache.linkis.common.io.FsPath
+
+import scala.beans.BeanProperty
+
+package object emailcontent {
+
+}
+
+class PictureEmailContent extends ArrayEmailContent with FsPathStoreEmailContent {
+
+ def this(filePath: FsPath) = {
+ this()
+ setFsPath(filePath)
+ }
+
+}
+
+class HtmlEmailContent extends StringEmailContent with FsPathStoreEmailContent {
+
+ def this(filePath: FsPath) = {
+ this()
+ setFsPath(filePath)
+ }
+
+}
+
+class TableEmailContent extends StringEmailContent with FsPathStoreEmailContent {
+
+ def this(filePath: FsPath) = {
+ this()
+ setFsPath(filePath)
+ }
+
+}
+
+class FileEmailContent extends StringEmailContent with FsPathStoreEmailContent {
+
+ def this(filePath: FsPath) = {
+ this()
+ setFsPath(filePath)
+ }
+
+}
+
+class TextEmailContent extends StringEmailContent {
+
+ def this(text: String) = {
+ this()
+ setContent(text)
+ }
+
+}
+
+class UrlEmailContent extends StringEmailContent {
+
+ @BeanProperty var url: String = _
+
+ def this(url: String) = {
+ this()
+ this.url = url
+ }
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/AbstractEmailContentGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/AbstractEmailContentGenerator.scala
new file mode 100644
index 000000000..d2b1e99f6
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/AbstractEmailContentGenerator.scala
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.generator
+
+import java.text.SimpleDateFormat
+import java.util.{Calendar, Date}
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.EmailContentGenerator
+
+
+trait AbstractEmailContentGenerator extends EmailContentGenerator {
+
+ protected def formatSubjectOfOldVersion(email: Email): Unit = {
+ var title = email.getSubject
+ if (title.contains("YYYY-MM-DD HH:MM:SS")) {
+ val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ val timeStr = sdf.format(new Date)
+ title = title.replace("YYYY-MM-DD HH:MM:SS", timeStr)
+ } else if (title.contains("YYYY-MM-DD-1")) {
+ val sdf = new SimpleDateFormat("yyyy-MM-dd")
+ val calendar = Calendar.getInstance
+ calendar.add(Calendar.DATE, -1)
+ val timeStr = sdf.format(calendar.getTime)
+ title = title.replace("YYYY-MM-DD-1", timeStr)
+ } else if (title.contains("YYYY-MM-DD")) {
+ val sdf = new SimpleDateFormat("yyyy-MM-dd")
+ val timeStr = sdf.format(new Date)
+ title = title.replace("YYYY-MM-DD", timeStr)
+ } else {
+ if (title.contains("NO_TIMESTAMP")) {
+ title = title.replaceAll("NO_TIMESTAMP", "")
+ } else {
+ val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ val timeStr = sdf.format(new Date)
+ title = title + timeStr
+ }
+ }
+ email.setSubject(title)
+ }
+
+ protected def formatSubject(email: Email): Unit = {
+
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/MultiEmailContentGenerator.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/MultiEmailContentGenerator.scala
new file mode 100644
index 000000000..af40d314c
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/generator/MultiEmailContentGenerator.scala
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.generator
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.MultiContentEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.{ArrayEmailContent, StringEmailContent}
+import org.apache.linkis.common.utils.Logging
+
+
+class MultiEmailContentGenerator extends AbstractEmailContentGenerator with Logging {
+
+ override def generate(email: Email): Unit = email match {
+ case multiContentEmail: MultiContentEmail =>
+ formatSubjectOfOldVersion(email)
+ formatSubject(multiContentEmail)
+ formatContent(multiContentEmail)
+ }
+
+ protected def formatContent(email: MultiContentEmail): Unit = {
+ val sb: StringBuilder = new StringBuilder("")
+ sb.append("")
+ email.getEmailContents.foreach {
+ case emailContent: ArrayEmailContent =>
+ emailContent.getContent.foreach(content => sb.append("").append(content).append(" |
"))
+ case emailContent: StringEmailContent =>
+ sb.append("").append(emailContent.getContent).append(" |
")
+ }
+ sb.append("
")
+ sb.append("")
+ email.setContent(sb.toString)
+ }
+
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/AbstractEmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/AbstractEmailContentParser.scala
new file mode 100644
index 000000000..2bbcb6c21
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/AbstractEmailContentParser.scala
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser
+
+import java.lang.reflect.{ParameterizedType, Type}
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.MultiContentEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.FsPathStoreEmailContent
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.{EmailContent, EmailContentParser}
+import org.apache.linkis.common.io.resultset.ResultSetReader
+import org.apache.linkis.common.io.{MetaData, Record}
+import org.apache.linkis.common.utils.Utils
+import org.apache.linkis.storage.LineRecord
+import org.apache.linkis.storage.resultset.ResultSetReader
+import org.apache.commons.io.IOUtils
+
+abstract class AbstractEmailContentParser[T] extends EmailContentParser {
+
+ override def parse(email: Email): Unit = email match {
+ case multiContentEmail: MultiContentEmail =>
+ multiContentEmail.getEmailContents.foreach {
+ case t: EmailContent[_] if t.getClass == getEmailContentClass =>
+ parseEmailContent(t.asInstanceOf[T], multiContentEmail)
+ case _ =>
+ }
+ case _ =>
+ }
+
+ protected def getResultSetReader(fsPathStore: FsPathStoreEmailContent): ResultSetReader[_ <: MetaData, _ <: Record] = {
+ val reader = ResultSetReader.getResultSetReader(fsPathStore.getFsPath.getSchemaPath)
+ reader.getMetaData
+ reader
+ }
+
+ protected def getFirstLineRecord(fsPathStore: FsPathStoreEmailContent): Option[String] = {
+ val reader = getResultSetReader(fsPathStore)
+ if(!reader.hasNext) None
+ else Utils.tryFinally(reader.getRecord match {
+ case record: LineRecord => Option(record.getLine)
+ })(IOUtils.closeQuietly(reader))
+ }
+
+ protected def getEmailContentClass: Type = getClass.getGenericSuperclass match {
+ case pType: ParameterizedType => pType.getActualTypeArguments.head
+ }
+
+ protected def parseEmailContent(emailContent: T,
+ multiContentEmail: MultiContentEmail): Unit
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/FileEmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/FileEmailContentParser.scala
new file mode 100644
index 000000000..a6aa2daf9
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/FileEmailContentParser.scala
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.MultiContentEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.FileEmailContent
+import org.apache.linkis.common.utils.Utils
+import org.apache.linkis.storage.LineRecord
+import org.apache.commons.io.IOUtils
+
+object FileEmailContentParser extends AbstractEmailContentParser[FileEmailContent] {
+ override protected def parseEmailContent(emailContent: FileEmailContent,
+ multiContentEmail: MultiContentEmail): Unit = {
+ val reader = getResultSetReader(emailContent)
+ val content = new StringBuilder
+ Utils.tryFinally{
+ while(reader.hasNext) {
+ reader.getRecord match {
+ case lineRecord: LineRecord =>
+ content.append(lineRecord.getLine).append("
")
+ }
+ }
+ }(IOUtils.closeQuietly(reader))
+ emailContent.setContent(content.toString())
+ }
+}
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/HtmlEmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/HtmlEmailContentParser.scala
new file mode 100644
index 000000000..cab083f70
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/HtmlEmailContentParser.scala
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.MultiContentEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.HtmlEmailContent
+
+object HtmlEmailContentParser extends AbstractEmailContentParser[HtmlEmailContent] {
+ override protected def parseEmailContent(emailContent: HtmlEmailContent,
+ multiContentEmail: MultiContentEmail): Unit = {
+ getFirstLineRecord(emailContent).foreach(emailContent.setContent)
+ }
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/PictureEmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/PictureEmailContentParser.scala
new file mode 100644
index 000000000..516248608
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/PictureEmailContentParser.scala
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser
+
+import java.awt.image.BufferedImage
+import java.io.{ByteArrayInputStream, ByteArrayOutputStream}
+import java.util.{Base64, UUID}
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.{AbstractEmail, MultiContentEmail, PngAttachment}
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.PictureEmailContent
+import org.apache.linkis.common.conf.Configuration
+import javax.imageio.ImageIO
+import org.apache.commons.codec.binary.Base64OutputStream
+import com.webank.wedatasphere.dss.appconn.sendemail.conf.SendEmailAppConnConfiguration._
+
+object PictureEmailContentParser extends AbstractEmailContentParser[PictureEmailContent] {
+
+ override protected def parseEmailContent(emailContent: PictureEmailContent,
+ multiContentEmail: MultiContentEmail): Unit = {
+ getFirstLineRecord(emailContent).foreach { imageStr =>
+ val decoder = Base64.getDecoder
+ val byteArr = decoder.decode(imageStr)
+ val inputStream = new ByteArrayInputStream(byteArr)
+ val image = ImageIO.read(inputStream)
+ val contents = generateImage(image, multiContentEmail)
+ emailContent.setContent(contents)
+ }
+ }
+
+ protected def generateImage(bufferedImage: BufferedImage, email: AbstractEmail): Array[String] = {
+ val imageUUID: String = UUID.randomUUID.toString
+ val width: Int = bufferedImage.getWidth
+ val height: Int = bufferedImage.getHeight
+ // 只支持修改visualis图片大小,后续如果有新增其他类型的邮件需要修改图片大小,需要在if中加上该邮件类型
+ val imagesCuts = if (email.getEmailType.contains("visualis") && height > EMAIL_IMAGE_HEIGHT.getValue) {
+ val numOfCut = Math.ceil(height.toDouble / EMAIL_IMAGE_HEIGHT.getValue).toInt
+ val realHeight = height / numOfCut
+ (0 until numOfCut).map(i => bufferedImage.getSubimage(0, i * realHeight, width, realHeight)).toArray
+ } else Array(bufferedImage)
+ imagesCuts.indices.map { index =>
+ val image = imagesCuts(index)
+ val imageName = index + "_" + imageUUID + ".png"
+ val os = new ByteArrayOutputStream
+ val b64Stream = new Base64OutputStream(os)
+ ImageIO.write(image, "png", b64Stream)
+ val b64 = os.toString(Configuration.BDP_ENCODING.getValue)
+ email.addAttachment(new PngAttachment(imageName, b64))
+
+ var iHeight = image.getHeight
+ var iWidth = image.getWidth
+
+ if (email.getEmailType.contains("visualis") && iWidth > EMAIL_IMAGE_WIDTH.getValue) {
+ iHeight = ((EMAIL_IMAGE_WIDTH.getValue.toDouble / iWidth.toDouble) * iHeight.toDouble).toInt
+ iWidth = EMAIL_IMAGE_WIDTH.getValue
+ }
+ s""""""
+ }.toArray
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/TableEmailContentParser.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/TableEmailContentParser.scala
new file mode 100644
index 000000000..71dbd7709
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/emailcontent/parser/TableEmailContentParser.scala
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.parser
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.domain.MultiContentEmail
+import com.webank.wedatasphere.dss.appconn.sendemail.emailcontent.domain.TableEmailContent
+import org.apache.linkis.common.utils.Utils
+import org.apache.linkis.storage.resultset.table.{TableMetaData, TableRecord}
+import org.apache.commons.io.IOUtils
+import org.apache.commons.lang.StringUtils
+
+object TableEmailContentParser extends AbstractEmailContentParser[TableEmailContent] {
+ override protected def parseEmailContent(emailContent: TableEmailContent,
+ multiContentEmail: MultiContentEmail): Unit = {
+ val reader = getResultSetReader(emailContent)
+ val content = new StringBuilder
+ reader.getMetaData match {
+ case tableMetaData: TableMetaData =>
+ writeTableTH(tableMetaData, content)
+ }
+ Utils.tryFinally {
+ while(reader.hasNext) {
+ reader.getRecord match {
+ case tableRecord: TableRecord =>
+ writeTableTR(tableRecord, content)
+ }
+ }
+ }(IOUtils.closeQuietly(reader))
+ emailContent.setContent(content.toString())
+ }
+
+ protected def writeTableTH(tableMetaData: TableMetaData, content: StringBuilder): Unit = {
+ content.append("")
+ tableMetaData.columns.foreach{ c =>
+ content.append(" | ").append(c.columnName)
+ if(StringUtils.isNotBlank(c.comment)) {
+ val comment = if(c.comment.length < 10) c.comment else c.comment.substring(0, 9) + "..."
+ content.append("(").append(comment).append(")")
+ }
+ content.append(" | ")
+ }
+ content.append("")
+ }
+
+ protected def writeTableTR(tableRecord: TableRecord, content: StringBuilder): Unit = {
+ content.append("")
+ tableRecord.row.foreach(v => content.append("").append(v).append(" | "))
+ content.append("
")
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/AbstractSendEmailRefExecutionHook.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/AbstractSendEmailRefExecutionHook.scala
new file mode 100644
index 000000000..294e385f5
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/AbstractSendEmailRefExecutionHook.scala
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+import com.webank.wedatasphere.dss.standard.app.development.listener.core.ExecutionRequestRefContext
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.RefExecutionRequestRef
+
+abstract class AbstractSendEmailRefExecutionHook extends SendEmailRefExecutionHook {
+
+ protected def getExecutionRequestRefContext(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): ExecutionRequestRefContext =
+ requestRef.getExecutionRequestRefContext
+
+ override def preSend(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl, email: Email): Unit = {}
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/SendEmailRefExecutionHook.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/SendEmailRefExecutionHook.scala
new file mode 100644
index 000000000..37838fe49
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/com/webank/wedatasphere/dss/appconn/sendemail/hook/SendEmailRefExecutionHook.scala
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.sendemail.hook
+
+import com.webank.wedatasphere.dss.appconn.sendemail.email.Email
+import com.webank.wedatasphere.dss.appconn.sendemail.exception.EmailSendFailedException
+import com.webank.wedatasphere.dss.standard.app.development.listener.ref.RefExecutionRequestRef
+
+
+trait SendEmailRefExecutionHook {
+
+ @throws(classOf[EmailSendFailedException])
+ def preGenerate(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl): Unit
+
+ def preSend(requestRef: RefExecutionRequestRef.RefExecutionRequestRefImpl, email: Email): Unit
+
+}
diff --git a/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/org/apache/linkis/server/JSONUtils.scala b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/org/apache/linkis/server/JSONUtils.scala
new file mode 100644
index 000000000..4474122fc
--- /dev/null
+++ b/dss-appconn/appconns/dss-sendemail-appconn/sendemail-appconn-core/src/main/scala/org/apache/linkis/server/JSONUtils.scala
@@ -0,0 +1,14 @@
+package org.apache.linkis.server
+
+/**
+ *
+ * @date 2022-03-11
+ * @author enjoyyin
+ * @since 0.5.0
+ */
+object JSONUtils {
+
+ val gson = BDPJettyServerHelper.gson
+
+ val jackson = BDPJettyServerHelper.jacksonJson
+}
diff --git a/dss-appconn/appconns/dss-sso-appconn/pom.xml b/dss-appconn/appconns/dss-sso-appconn/pom.xml
new file mode 100644
index 000000000..74e1b099e
--- /dev/null
+++ b/dss-appconn/appconns/dss-sso-appconn/pom.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+ dss
+ com.webank.wedatasphere.dss
+ 1.1.0
+ ../../../pom.xml
+
+ 4.0.0
+
+ dss-sso-appconn
+
+
+ com.webank.wedatasphere.dss
+ dss-appconn-core
+ ${dss.version}
+ provided
+
+
+ com.webank.wedatasphere.dss
+ dss-orchestrator-core
+ ${dss.version}
+ provided
+
+
+
+ com.webank.wedatasphere.dss
+ dss-common
+ ${dss.version}
+ provided
+
+
+ com.webank.wedatasphere.dss
+ dss-sender-service
+ ${dss.version}
+ provided
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.3
+ false
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+ false
+ out
+ false
+ false
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-sso-appconn/src/main/assembly/distribution.xml b/dss-appconn/appconns/dss-sso-appconn/src/main/assembly/distribution.xml
new file mode 100644
index 000000000..c186e12f6
--- /dev/null
+++ b/dss-appconn/appconns/dss-sso-appconn/src/main/assembly/distribution.xml
@@ -0,0 +1,74 @@
+
+
+
+ dss-sso-appconn
+
+ dir
+
+ true
+ sso
+
+
+
+
+
+ lib
+ true
+ true
+ false
+ true
+ true
+
+
+
+
+
+
+
+ ${basedir}/conf
+
+ *
+
+ 0777
+ conf
+ unix
+
+
+ .
+
+ */**
+
+ logs
+
+
+
+ ${basedir}/src/main/resources
+
+ init.sql
+
+ 0777
+ db
+
+
+
+
+
+
+
diff --git a/dss-appconn/appconns/dss-sso-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/sso/SSOAppConn.java b/dss-appconn/appconns/dss-sso-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/sso/SSOAppConn.java
new file mode 100644
index 000000000..22500e945
--- /dev/null
+++ b/dss-appconn/appconns/dss-sso-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/sso/SSOAppConn.java
@@ -0,0 +1,17 @@
+package com.webank.wedatasphere.dss.appconn.sso;
+
+import com.webank.wedatasphere.dss.appconn.core.impl.AbstractOnlySSOAppConn;
+
+/**
+ * @author enjoyyin
+ * @date 2022-03-31
+ * @since 1.1.0
+ */
+public class SSOAppConn extends AbstractOnlySSOAppConn {
+ @Override
+ protected void initialize() {
+ if(getAppDesc() != null) {
+ logger.info("Load a SSOAppConn " + getAppDesc().getAppName());
+ }
+ }
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/pom.xml b/dss-appconn/appconns/dss-workflow-appconn/pom.xml
new file mode 100644
index 000000000..d9c115b1d
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/pom.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+ dss
+ com.webank.wedatasphere.dss
+ 1.1.0
+ ../../../pom.xml
+
+ 4.0.0
+
+ dss-workflow-appconn
+
+
+ com.webank.wedatasphere.dss
+ dss-development-process-standard
+ ${dss.version}
+ provided
+
+
+ com.webank.wedatasphere.dss
+ dss-appconn-core
+ ${dss.version}
+ provided
+
+
+ com.webank.wedatasphere.dss
+ dss-orchestrator-core
+ ${dss.version}
+ provided
+
+
+
+ com.webank.wedatasphere.dss
+ dss-common
+ ${dss.version}
+ provided
+
+
+ com.webank.wedatasphere.dss
+ dss-sender-service
+ ${dss.version}
+ provided
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.3
+ false
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+ false
+ out
+ false
+ false
+
+ src/main/assembly/distribution.xml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/assembly/distribution.xml b/dss-appconn/appconns/dss-workflow-appconn/src/main/assembly/distribution.xml
new file mode 100644
index 000000000..003e51313
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/assembly/distribution.xml
@@ -0,0 +1,66 @@
+
+
+
+ dss-workflow-appconn
+
+ dir
+
+ true
+ workflow
+
+
+
+
+
+ lib
+ true
+ true
+ false
+ true
+ true
+
+
+
+
+
+ ${basedir}/src/main/resources
+
+ appconn.properties
+
+ 0777
+ /
+ unix
+
+
+
+ ${basedir}/src/main/resources
+
+ log4j.properties
+ log4j2.xml
+
+ 0777
+ conf
+ unix
+
+
+
+
+
+
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowAppConn.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowAppConn.java
new file mode 100644
index 000000000..964c38831
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowAppConn.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow;
+
+import com.webank.wedatasphere.dss.appconn.core.ext.OnlyDevelopmentAppConn;
+import com.webank.wedatasphere.dss.appconn.core.impl.AbstractAppConn;
+import com.webank.wedatasphere.dss.standard.app.development.standard.DevelopmentIntegrationStandard;
+
+public class WorkflowAppConn extends AbstractAppConn implements OnlyDevelopmentAppConn {
+
+ private DevelopmentIntegrationStandard developmentIntegrationStandard = new WorkflowDevelopmentIntegrationStandard();
+
+ @Override
+ protected void initialize() {
+ }
+
+ @Override
+ public DevelopmentIntegrationStandard getOrCreateDevelopmentStandard() {
+ return developmentIntegrationStandard;
+ }
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowDevelopmentIntegrationStandard.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowDevelopmentIntegrationStandard.java
new file mode 100644
index 000000000..f93d4c396
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/WorkflowDevelopmentIntegrationStandard.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow;
+
+import com.webank.wedatasphere.dss.appconn.workflow.service.WorkflowCRUDService;
+import com.webank.wedatasphere.dss.appconn.workflow.service.WorkflowExportService;
+import com.webank.wedatasphere.dss.appconn.workflow.service.WorkflowImportService;
+import com.webank.wedatasphere.dss.appconn.workflow.service.WorkflowQueryService;
+import com.webank.wedatasphere.dss.standard.app.development.service.*;
+import com.webank.wedatasphere.dss.standard.app.development.standard.AbstractDevelopmentIntegrationStandard;
+
+public class WorkflowDevelopmentIntegrationStandard extends AbstractDevelopmentIntegrationStandard {
+
+ @Override
+ protected RefCRUDService createRefCRUDService() {
+ return new WorkflowCRUDService();
+ }
+
+ @Override
+ protected RefExecutionService createRefExecutionService() {
+ return null;
+ }
+
+ @Override
+ protected RefExportService createRefExportService() {
+ return new WorkflowExportService();
+ }
+
+ @Override
+ protected RefImportService createRefImportService() {
+ return new WorkflowImportService();
+ }
+
+ @Override
+ protected RefQueryService createRefQueryService() {
+ return new WorkflowQueryService();
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCopyOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCopyOperation.java
new file mode 100644
index 000000000..28d8a9781
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCopyOperation.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.orchestrator.common.ref.OrchestratorRefConstant;
+import com.webank.wedatasphere.dss.sender.service.DSSSenderServiceFactory;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefCopyOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.RefJobContentResponseRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.ThirdlyRequestRef;
+import com.webank.wedatasphere.dss.workflow.common.protocol.RequestCopyWorkflow;
+import com.webank.wedatasphere.dss.workflow.common.protocol.ResponseCopyWorkflow;
+import org.apache.linkis.rpc.Sender;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class WorkflowRefCopyOperation
+ extends AbstractDevelopmentOperation
+ implements RefCopyOperation {
+
+ private final Sender sender = DSSSenderServiceFactory.getOrCreateServiceInstance().getWorkflowSender();
+
+ @Override
+ public RefJobContentResponseRef copyRef(ThirdlyRequestRef.CopyWitContextRequestRefImpl workflowCopyRequestRef) {
+ Long appId = (Long) workflowCopyRequestRef.getRefJobContent().get(OrchestratorRefConstant.ORCHESTRATION_ID_KEY);
+ String userName = workflowCopyRequestRef.getUserName();
+ String contextIdStr = workflowCopyRequestRef.getContextId();
+ String projectName = workflowCopyRequestRef.getProjectName();
+ //插入version
+ String version = workflowCopyRequestRef.getNewVersion();
+ String description = (String) workflowCopyRequestRef.getRefJobContent().get(OrchestratorRefConstant.ORCHESTRATION_DESCRIPTION);
+ RequestCopyWorkflow requestCopyWorkflow = new RequestCopyWorkflow(userName,
+ workflowCopyRequestRef.getWorkspace(), appId, contextIdStr,
+ projectName, version, description, workflowCopyRequestRef.getDSSLabels());
+ ResponseCopyWorkflow responseCopyWorkflow = (ResponseCopyWorkflow) sender.ask(requestCopyWorkflow);
+ Map refJobContent = new HashMap<>(2);
+ refJobContent.put(OrchestratorRefConstant.ORCHESTRATION_ID_KEY, responseCopyWorkflow.getDssFlow().getId());
+ refJobContent.put(OrchestratorRefConstant.ORCHESTRATION_CONTENT_KEY, responseCopyWorkflow.getDssFlow().getFlowJson());
+ return RefJobContentResponseRef.newBuilder().setRefJobContent(refJobContent).success();
+ }
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCreationOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCreationOperation.java
new file mode 100644
index 000000000..9fcbc1407
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefCreationOperation.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.common.label.DSSLabel;
+import com.webank.wedatasphere.dss.common.utils.MapUtils;
+import com.webank.wedatasphere.dss.orchestrator.common.entity.DSSOrchestratorInfo;
+import com.webank.wedatasphere.dss.orchestrator.common.ref.OrchestratorRefConstant;
+import com.webank.wedatasphere.dss.sender.service.DSSSenderServiceFactory;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefCreationOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.RefJobContentResponseRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.ThirdlyRequestRef;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationFailedException;
+import com.webank.wedatasphere.dss.workflow.common.protocol.RequestCreateWorkflow;
+import com.webank.wedatasphere.dss.workflow.common.protocol.ResponseCreateWorkflow;
+import org.apache.linkis.rpc.Sender;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class WorkflowRefCreationOperation
+ extends AbstractDevelopmentOperation
+ implements RefCreationOperation {
+
+ private Sender sender = DSSSenderServiceFactory.getOrCreateServiceInstance().getWorkflowSender();
+
+ @Override
+ public RefJobContentResponseRef createRef(ThirdlyRequestRef.DSSJobContentWithContextRequestRef requestRef) throws ExternalOperationFailedException {
+ //发送RPC请求
+ DSSOrchestratorInfo dssOrchestratorInfo = (DSSOrchestratorInfo) requestRef.getDSSJobContent().get(OrchestratorRefConstant.DSS_ORCHESTRATOR_INFO_KEY);
+ String userName = requestRef.getUserName();
+ String workflowName = dssOrchestratorInfo.getName();
+ String contextId = requestRef.getContextId() != null ? requestRef.getContextId() : "";
+ String description = dssOrchestratorInfo.getDesc();
+ List dssLabels = requestRef.getDSSLabels();
+ String orcVersion = (String) requestRef.getDSSJobContent().get(OrchestratorRefConstant.ORCHESTRATOR_VERSION_KEY);
+ String schedulerAppConnName = (String) requestRef.getDSSJobContent().get(OrchestratorRefConstant.ORCHESTRATION_SCHEDULER_APP_CONN);
+ long parentFlowId = -1L;
+ List linkedAppConnNames = dssOrchestratorInfo.getLinkedAppConnNames() != null ?
+ dssOrchestratorInfo.getLinkedAppConnNames() : new ArrayList<>();
+ String uses = dssOrchestratorInfo.getUses() != null ?
+ dssOrchestratorInfo.getUses() : "uses";
+ RequestCreateWorkflow requestCreateWorkflow = new RequestCreateWorkflow(userName, dssOrchestratorInfo.getProjectId(), workflowName,
+ contextId, description, parentFlowId, uses, linkedAppConnNames, dssLabels, orcVersion, schedulerAppConnName);
+
+ ResponseCreateWorkflow responseCreateWorkflow = (ResponseCreateWorkflow) sender.ask(requestCreateWorkflow);
+ Map refJobContent = MapUtils.newCommonMap(OrchestratorRefConstant.ORCHESTRATION_ID_KEY, responseCreateWorkflow.getDssFlow().getId(),
+ OrchestratorRefConstant.ORCHESTRATION_CONTENT_KEY, responseCreateWorkflow.getDssFlow().getFlowJson());
+ return RefJobContentResponseRef.newBuilder().setRefJobContent(refJobContent).success();
+ }
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefDeletionOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefDeletionOperation.java
new file mode 100644
index 000000000..fbf6fd365
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefDeletionOperation.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.common.label.DSSLabel;
+import com.webank.wedatasphere.dss.common.protocol.JobStatus;
+import com.webank.wedatasphere.dss.common.protocol.RequestDeleteWorkflow;
+import com.webank.wedatasphere.dss.orchestrator.common.ref.OrchestratorRefConstant;
+import com.webank.wedatasphere.dss.sender.service.DSSSenderServiceFactory;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefDeletionOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.OnlyDevelopmentRequestRef;
+import com.webank.wedatasphere.dss.standard.common.entity.ref.ResponseRef;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationFailedException;
+import com.webank.wedatasphere.dss.workflow.common.protocol.ResponseDeleteWorkflow;
+import org.apache.linkis.rpc.Sender;
+
+import java.util.List;
+
+
+public class WorkflowRefDeletionOperation
+ extends AbstractDevelopmentOperation
+ implements RefDeletionOperation {
+
+ @Override
+ public ResponseRef deleteRef(OnlyDevelopmentRequestRef.RefJobContentRequestRefImpl requestRef) throws ExternalOperationFailedException {
+ String userName = requestRef.getUserName();
+ Long flowId = (Long) requestRef.getRefJobContent().get(OrchestratorRefConstant.ORCHESTRATION_ID_KEY);
+ RequestDeleteWorkflow requestDeleteWorkflow = new RequestDeleteWorkflow(userName, flowId);
+ List dssLabels = requestRef.getDSSLabels();
+ Sender tempSend = DSSSenderServiceFactory.getOrCreateServiceInstance().getWorkflowSender(dssLabels);
+ ResponseDeleteWorkflow responseDeleteWorkflow = (ResponseDeleteWorkflow) tempSend.ask(requestDeleteWorkflow);
+ if(responseDeleteWorkflow.getJobStatus() == JobStatus.Success) {
+ return ResponseRef.newInternalBuilder().success();
+ } else {
+ return ResponseRef.newInternalBuilder().error("Unknown error, please ask admin for help.");
+ }
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefExportOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefExportOperation.java
new file mode 100644
index 000000000..9b1c5c12c
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefExportOperation.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.common.protocol.RequestExportWorkflow;
+import com.webank.wedatasphere.dss.common.protocol.ResponseExportWorkflow;
+import com.webank.wedatasphere.dss.orchestrator.common.ref.OrchestratorRefConstant;
+import com.webank.wedatasphere.dss.sender.service.DSSSenderServiceFactory;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefExportOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.ExportResponseRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.ImportRequestRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.ThirdlyRequestRef;
+import org.apache.linkis.rpc.Sender;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class WorkflowRefExportOperation
+ extends AbstractDevelopmentOperation
+ implements RefExportOperation {
+
+ @Override
+ public ExportResponseRef exportRef(ThirdlyRequestRef.RefJobContentRequestRefImpl requestRef) {
+
+ String userName = requestRef.getUserName();
+ long flowId = (long) requestRef.getRefJobContent().get(OrchestratorRefConstant.ORCHESTRATION_ID_KEY);
+ Long projectId = requestRef.getRefProjectId();
+ String projectName = requestRef.getProjectName();
+ RequestExportWorkflow requestExportWorkflow = new RequestExportWorkflow(userName,
+ flowId,
+ projectId,
+ projectName,
+ toJson(requestRef.getWorkspace()),
+ requestRef.getDSSLabels());
+ Sender sender = DSSSenderServiceFactory.getOrCreateServiceInstance().getWorkflowSender(requestRef.getDSSLabels());
+ ResponseExportWorkflow responseExportWorkflow = (ResponseExportWorkflow) sender.ask(requestExportWorkflow);
+ Map resourceMap = new HashMap<>(2);
+ resourceMap.put(ImportRequestRef.RESOURCE_ID_KEY, responseExportWorkflow.resourceId());
+ resourceMap.put(ImportRequestRef.RESOURCE_VERSION_KEY, responseExportWorkflow.version());
+ return ExportResponseRef.newBuilder().setResourceMap(resourceMap).success();
+ }
+
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefImportOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefImportOperation.java
new file mode 100644
index 000000000..19c2172bf
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefImportOperation.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.common.protocol.JobStatus;
+import com.webank.wedatasphere.dss.common.utils.MapUtils;
+import com.webank.wedatasphere.dss.orchestrator.common.ref.OrchestratorRefConstant;
+import com.webank.wedatasphere.dss.sender.service.DSSSenderServiceFactory;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefImportOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.ImportRequestRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.RefJobContentResponseRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.ThirdlyRequestRef;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationFailedException;
+import com.webank.wedatasphere.dss.workflow.common.protocol.RequestImportWorkflow;
+import com.webank.wedatasphere.dss.workflow.common.protocol.ResponseImportWorkflow;
+import org.apache.linkis.rpc.Sender;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class WorkflowRefImportOperation
+ extends AbstractDevelopmentOperation
+ implements RefImportOperation {
+
+ @Override
+ public RefJobContentResponseRef importRef(ThirdlyRequestRef.ImportWitContextRequestRefImpl requestRef) throws ExternalOperationFailedException {
+ RequestImportWorkflow requestImportWorkflow = new RequestImportWorkflow(requestRef.getUserName(),
+ (String) requestRef.getResourceMap().get(ImportRequestRef.RESOURCE_ID_KEY),
+ (String) requestRef.getResourceMap().get(ImportRequestRef.RESOURCE_VERSION_KEY),
+ requestRef.getRefProjectId(), requestRef.getProjectName(),
+ requestRef.getNewVersion(),
+ requestRef.getWorkspace(),
+ requestRef.getContextId(), requestRef.getDSSLabels());
+
+ Sender sender = DSSSenderServiceFactory.getOrCreateServiceInstance().getWorkflowSender(requestRef.getDSSLabels());
+ ResponseImportWorkflow responseImportWorkflow = (ResponseImportWorkflow) sender.ask(requestImportWorkflow);
+ if(responseImportWorkflow.getStatus() == JobStatus.Success) {
+ if(MapUtils.isEmpty(responseImportWorkflow.getWorkflows())) {
+ return RefJobContentResponseRef.newBuilder()
+ .error("Empty workflow returned from workflow server, please ask admin for help!");
+ }
+ Map refMap = new HashMap<>(2);
+ responseImportWorkflow.getWorkflows().forEach((key, value) -> {
+ refMap.put(OrchestratorRefConstant.ORCHESTRATION_ID_KEY, key);
+ refMap.put(OrchestratorRefConstant.ORCHESTRATION_CONTENT_KEY, value);
+ });
+ return RefJobContentResponseRef.newBuilder().setRefJobContent(refMap).success();
+ } else {
+ return RefJobContentResponseRef.newBuilder().error("Unknown reason, please ask admin for help.");
+ }
+ }
+}
diff --git a/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefQueryOperation.java b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefQueryOperation.java
new file mode 100644
index 000000000..98f5f1ca5
--- /dev/null
+++ b/dss-appconn/appconns/dss-workflow-appconn/src/main/java/com/webank/wedatasphere/dss/appconn/workflow/opertion/WorkflowRefQueryOperation.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 WeBank
+ * 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 com.webank.wedatasphere.dss.appconn.workflow.opertion;
+
+import com.webank.wedatasphere.dss.common.label.EnvDSSLabel;
+import com.webank.wedatasphere.dss.standard.app.development.operation.AbstractDevelopmentOperation;
+import com.webank.wedatasphere.dss.standard.app.development.operation.RefQueryJumpUrlOperation;
+import com.webank.wedatasphere.dss.standard.app.development.ref.QueryJumpUrlResponseRef;
+import com.webank.wedatasphere.dss.standard.app.development.ref.impl.OnlyDevelopmentRequestRef;
+import com.webank.wedatasphere.dss.standard.common.exception.operation.ExternalOperationWarnException;
+
+public class WorkflowRefQueryOperation
+ extends AbstractDevelopmentOperation
+ implements RefQueryJumpUrlOperation