wuxiaofei 4 years ago
parent
commit
2cfe755abb
  1. 122
      .gitignore
  2. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java
  3. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java
  4. 4
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/EmailConstants.java
  5. 13
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/ExcelUtils.java
  6. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/MailParamsConstants.java
  7. 64
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/MailSender.java
  8. 40
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/exception/AlertEmailException.java
  9. 9
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/template/DefaultHTMLTemplate.java
  10. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/OSUtils.java
  11. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/ScriptParamsConstants.java
  12. 2
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/StreamGobbler.java
  13. 4
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertConstants.java
  14. 3
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertParamsConstants.java
  15. 47
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java
  16. 30
      dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/exception/WeChatAlertException.java
  17. 32
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java
  18. 15
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
  19. 56
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptor.java
  20. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java
  21. 12
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java
  22. 21
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java
  23. 7
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java
  24. 48
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptorTest.java
  25. 8
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java
  26. 11
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
  27. 5
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
  28. 6
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/CollectionUtils.java
  29. 11
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/OSUtils.java
  30. 6
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapper.java
  31. 6
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapper.xml
  32. 8
      dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapperTest.java
  33. 2
      dolphinscheduler-dist/release-docs/LICENSE
  34. 21
      dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui
  35. 4
      dolphinscheduler-ui/package.json
  36. 2
      dolphinscheduler-ui/src/js/conf/home/index.js
  37. 55
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue
  38. 1
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue
  39. 4
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/udp/udp.vue
  40. 2
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/_source/conditions/instance/processInstance.vue
  41. 26
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  42. 31
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue
  43. 26
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
  44. 23
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue
  45. 4
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  46. 16
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/list/_source/createProject.vue
  47. 2
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/list/index.vue
  48. 21
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/_source/createQueue.vue
  49. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue
  50. 19
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/_source/createTenement.vue
  51. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue
  52. 23
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue
  53. 4
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
  54. 2
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue
  55. 47
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
  56. 55
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
  57. 16
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
  58. 197
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
  59. 107
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue
  60. 171
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue
  61. 4
      dolphinscheduler-ui/src/js/conf/home/pages/user/pages/account/_source/info.vue
  62. 19
      dolphinscheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue
  63. 2
      dolphinscheduler-ui/src/js/conf/home/pages/user/pages/token/index.vue
  64. 16
      dolphinscheduler-ui/src/js/conf/home/router/index.js
  65. 2
      dolphinscheduler-ui/src/js/conf/home/store/dag/state.js
  66. 94
      dolphinscheduler-ui/src/js/conf/home/store/security/actions.js
  67. 97
      dolphinscheduler-ui/src/js/module/components/popup/popover.vue
  68. 9
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
  69. 5
      dolphinscheduler-ui/src/js/module/components/transfer/resource.vue
  70. 9
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  71. 6
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
  72. 4
      dolphinscheduler-ui/src/js/module/io/index.js
  73. 4
      dolphinscheduler-ui/src/sass/common/index.scss
  74. 3
      pom.xml
  75. 2
      tools/dependencies/known-dependencies.txt

122
.gitignore vendored

@ -4,15 +4,9 @@
.zip .zip
.gz .gz
.DS_Store .DS_Store
.idea
.idea/
.idea/*
.target .target
.target/ .idea/
**/**/target/** target/
target/*
*/target
*/target/*
.settings .settings
.nbproject .nbproject
.classpath .classpath
@ -28,123 +22,23 @@ node_modules
npm-debug.log npm-debug.log
.vscode .vscode
logs/* logs/*
.mvn/
.www .www
t.* t.*
.factorypath
Chart.lock
yarn.lock yarn.lock
package-lock.json package-lock.json
config.gypi config.gypi
test/coverage test/coverage
/docs/zh_CN/介绍 /docs/zh_CN/介绍
/docs/zh_CN/贡献代码.md /docs/zh_CN/贡献代码.md
/dolphinscheduler-common/src/main/resources/zookeeper.properties dolphinscheduler-common/src/main/resources/zookeeper.properties
dolphinscheduler-dao/src/main/resources/dao/data_source.properties
dolphinscheduler-alert/logs/ dolphinscheduler-alert/logs/
dolphinscheduler-alert/src/main/resources/alert.properties_bak dolphinscheduler-alert/src/main/resources/alert.properties_bak
dolphinscheduler-alert/src/main/resources/logback.xml dolphinscheduler-alert/src/main/resources/logback.xml
dolphinscheduler-server/src/main/resources/logback.xml dolphinscheduler-server/src/main/resources/logback.xml
dolphinscheduler-ui/dist dolphinscheduler-ui/dist
dolphinscheduler-ui/node dolphinscheduler-ui/node
dolphinscheduler-ui/dist/css/common.16ac5d9.css docker/build/apache-dolphinscheduler*
dolphinscheduler-ui/dist/css/home/index.b444b91.css
dolphinscheduler-ui/dist/css/login/index.5866c64.css
dolphinscheduler-ui/dist/js/0.ac94e5d.js
dolphinscheduler-ui/dist/js/0.ac94e5d.js.map
dolphinscheduler-ui/dist/js/1.0b043a3.js
dolphinscheduler-ui/dist/js/1.0b043a3.js.map
dolphinscheduler-ui/dist/js/10.1bce3dc.js
dolphinscheduler-ui/dist/js/10.1bce3dc.js.map
dolphinscheduler-ui/dist/js/11.79f04d8.js
dolphinscheduler-ui/dist/js/11.79f04d8.js.map
dolphinscheduler-ui/dist/js/12.420daa5.js
dolphinscheduler-ui/dist/js/12.420daa5.js.map
dolphinscheduler-ui/dist/js/13.e5bae1c.js
dolphinscheduler-ui/dist/js/13.e5bae1c.js.map
dolphinscheduler-ui/dist/js/14.f2a0dca.js
dolphinscheduler-ui/dist/js/14.f2a0dca.js.map
dolphinscheduler-ui/dist/js/15.45373e8.js
dolphinscheduler-ui/dist/js/15.45373e8.js.map
dolphinscheduler-ui/dist/js/16.fecb0fc.js
dolphinscheduler-ui/dist/js/16.fecb0fc.js.map
dolphinscheduler-ui/dist/js/17.84be279.js
dolphinscheduler-ui/dist/js/17.84be279.js.map
dolphinscheduler-ui/dist/js/18.307ea70.js
dolphinscheduler-ui/dist/js/18.307ea70.js.map
dolphinscheduler-ui/dist/js/19.144db9c.js
dolphinscheduler-ui/dist/js/19.144db9c.js.map
dolphinscheduler-ui/dist/js/2.8b4ef29.js
dolphinscheduler-ui/dist/js/2.8b4ef29.js.map
dolphinscheduler-ui/dist/js/20.4c527e9.js
dolphinscheduler-ui/dist/js/20.4c527e9.js.map
dolphinscheduler-ui/dist/js/21.831b2a2.js
dolphinscheduler-ui/dist/js/21.831b2a2.js.map
dolphinscheduler-ui/dist/js/22.2b4bb2a.js
dolphinscheduler-ui/dist/js/22.2b4bb2a.js.map
dolphinscheduler-ui/dist/js/23.81467ef.js
dolphinscheduler-ui/dist/js/23.81467ef.js.map
dolphinscheduler-ui/dist/js/24.54a00e4.js
dolphinscheduler-ui/dist/js/24.54a00e4.js.map
dolphinscheduler-ui/dist/js/25.8d7bd36.js
dolphinscheduler-ui/dist/js/25.8d7bd36.js.map
dolphinscheduler-ui/dist/js/26.2ec5e78.js
dolphinscheduler-ui/dist/js/26.2ec5e78.js.map
dolphinscheduler-ui/dist/js/27.3ab48c2.js
dolphinscheduler-ui/dist/js/27.3ab48c2.js.map
dolphinscheduler-ui/dist/js/28.363088a.js
dolphinscheduler-ui/dist/js/28.363088a.js.map
dolphinscheduler-ui/dist/js/29.6c5853a.js
dolphinscheduler-ui/dist/js/29.6c5853a.js.map
dolphinscheduler-ui/dist/js/3.a0edb5b.js
dolphinscheduler-ui/dist/js/3.a0edb5b.js.map
dolphinscheduler-ui/dist/js/30.940fdd3.js
dolphinscheduler-ui/dist/js/30.940fdd3.js.map
dolphinscheduler-ui/dist/js/31.168a460.js
dolphinscheduler-ui/dist/js/31.168a460.js.map
dolphinscheduler-ui/dist/js/32.8df6594.js
dolphinscheduler-ui/dist/js/32.8df6594.js.map
dolphinscheduler-ui/dist/js/33.4480bbe.js
dolphinscheduler-ui/dist/js/33.4480bbe.js.map
dolphinscheduler-ui/dist/js/34.b407fe1.js
dolphinscheduler-ui/dist/js/34.b407fe1.js.map
dolphinscheduler-ui/dist/js/35.f340b0a.js
dolphinscheduler-ui/dist/js/35.f340b0a.js.map
dolphinscheduler-ui/dist/js/36.8880c2d.js
dolphinscheduler-ui/dist/js/36.8880c2d.js.map
dolphinscheduler-ui/dist/js/37.ea2a25d.js
dolphinscheduler-ui/dist/js/37.ea2a25d.js.map
dolphinscheduler-ui/dist/js/38.98a59ee.js
dolphinscheduler-ui/dist/js/38.98a59ee.js.map
dolphinscheduler-ui/dist/js/39.a5e958a.js
dolphinscheduler-ui/dist/js/39.a5e958a.js.map
dolphinscheduler-ui/dist/js/4.4ca44db.js
dolphinscheduler-ui/dist/js/4.4ca44db.js.map
dolphinscheduler-ui/dist/js/40.e187b1e.js
dolphinscheduler-ui/dist/js/40.e187b1e.js.map
dolphinscheduler-ui/dist/js/41.0e89182.js
dolphinscheduler-ui/dist/js/41.0e89182.js.map
dolphinscheduler-ui/dist/js/42.341047c.js
dolphinscheduler-ui/dist/js/42.341047c.js.map
dolphinscheduler-ui/dist/js/43.27b8228.js
dolphinscheduler-ui/dist/js/43.27b8228.js.map
dolphinscheduler-ui/dist/js/44.e8869bc.js
dolphinscheduler-ui/dist/js/44.e8869bc.js.map
dolphinscheduler-ui/dist/js/45.8d54901.js
dolphinscheduler-ui/dist/js/45.8d54901.js.map
dolphinscheduler-ui/dist/js/5.e1ed7f3.js
dolphinscheduler-ui/dist/js/5.e1ed7f3.js.map
dolphinscheduler-ui/dist/js/6.241ba07.js
dolphinscheduler-ui/dist/js/6.241ba07.js.map
dolphinscheduler-ui/dist/js/7.ab2e297.js
dolphinscheduler-ui/dist/js/7.ab2e297.js.map
dolphinscheduler-ui/dist/js/8.83ff814.js
dolphinscheduler-ui/dist/js/8.83ff814.js.map
dolphinscheduler-ui/dist/js/9.39cb29f.js
dolphinscheduler-ui/dist/js/9.39cb29f.js.map
dolphinscheduler-ui/dist/js/common.733e342.js
dolphinscheduler-ui/dist/js/common.733e342.js.map
dolphinscheduler-ui/dist/js/home/index.78a5d12.js
dolphinscheduler-ui/dist/js/home/index.78a5d12.js.map
dolphinscheduler-ui/dist/js/login/index.291b8e3.js
dolphinscheduler-ui/dist/js/login/index.291b8e3.js.map
dolphinscheduler-ui/dist/lib/external/
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/index.vue
/dolphinscheduler-dao/src/main/resources/dao/data_source.properties

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkParamsConstants.java

@ -22,7 +22,7 @@ package org.apache.dolphinscheduler.plugin.alert.dingtalk;
*/ */
public class DingTalkParamsConstants { public class DingTalkParamsConstants {
public DingTalkParamsConstants() { private DingTalkParamsConstants() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-dingtalk/src/main/java/org/apache/dolphinscheduler/plugin/alert/dingtalk/DingTalkSender.java

@ -113,7 +113,7 @@ public class DingTalkSender {
} finally { } finally {
response.close(); response.close();
} }
logger.info("Ding Talk send [ %s ], resp:{%s}", msg, resp); logger.info("Ding Talk send {}, resp: {}", msg, resp);
return resp; return resp;
} finally { } finally {
httpClient.close(); httpClient.close();

4
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/EmailConstants.java

@ -19,6 +19,10 @@ package org.apache.dolphinscheduler.plugin.alert.email;
public class EmailConstants { public class EmailConstants {
private EmailConstants() {
throw new IllegalStateException(EmailConstants.class.getName());
}
public static final String XLS_FILE_PATH = "xls.file.path"; public static final String XLS_FILE_PATH = "xls.file.path";

13
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/ExcelUtils.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.plugin.alert.email; package org.apache.dolphinscheduler.plugin.alert.email;
import org.apache.dolphinscheduler.plugin.alert.email.exception.AlertEmailException;
import org.apache.dolphinscheduler.spi.utils.JSONUtils; import org.apache.dolphinscheduler.spi.utils.JSONUtils;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
@ -31,7 +32,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
*/ */
public class ExcelUtils { public class ExcelUtils {
public ExcelUtils() { private ExcelUtils() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
@ -65,16 +65,14 @@ public class ExcelUtils {
if (CollectionUtils.isEmpty(itemsList)) { if (CollectionUtils.isEmpty(itemsList)) {
logger.error("itemsList is null"); logger.error("itemsList is null");
throw new RuntimeException("itemsList is null"); throw new AlertEmailException("itemsList is null");
} }
LinkedHashMap<String, Object> headerMap = itemsList.get(0); LinkedHashMap<String, Object> headerMap = itemsList.get(0);
List<String> headerList = new ArrayList<>(); List<String> headerList = new ArrayList<>();
Iterator<Map.Entry<String, Object>> iter = headerMap.entrySet().iterator(); for (Map.Entry<String, Object> en : headerMap.entrySet()) {
while (iter.hasNext()) {
Map.Entry<String, Object> en = iter.next();
headerList.add(en.getKey()); headerList.add(en.getKey());
} }
@ -130,8 +128,7 @@ public class ExcelUtils {
wb.write(fos); wb.write(fos);
} catch (Exception e) { } catch (Exception e) {
logger.error("generate excel error", e); throw new AlertEmailException("generate excel error", e);
throw new RuntimeException("generate excel error", e);
} finally { } finally {
if (wb != null) { if (wb != null) {
try { try {

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/MailParamsConstants.java

@ -22,7 +22,7 @@ package org.apache.dolphinscheduler.plugin.alert.email;
*/ */
public class MailParamsConstants { public class MailParamsConstants {
public MailParamsConstants() { private MailParamsConstants() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }

64
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/MailSender.java

@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.plugin.alert.email;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import org.apache.dolphinscheduler.plugin.alert.email.exception.AlertEmailException;
import org.apache.dolphinscheduler.plugin.alert.email.template.AlertTemplate; import org.apache.dolphinscheduler.plugin.alert.email.template.AlertTemplate;
import org.apache.dolphinscheduler.plugin.alert.email.template.DefaultHTMLTemplate; import org.apache.dolphinscheduler.plugin.alert.email.template.DefaultHTMLTemplate;
import org.apache.dolphinscheduler.spi.alert.AlertConstants; import org.apache.dolphinscheduler.spi.alert.AlertConstants;
@ -67,7 +68,7 @@ public class MailSender {
private String mailProtocol = "SMTP"; private String mailProtocol = "SMTP";
private String mailSmtpHost; private String mailSmtpHost;
private String mailSmtpPort; private String mailSmtpPort;
private String mailSender; private String mailSenderEmail;
private String enableSmtpAuth; private String enableSmtpAuth;
private String mailUser; private String mailUser;
private String mailPasswd; private String mailPasswd;
@ -77,12 +78,13 @@ public class MailSender {
private String sslTrust; private String sslTrust;
private String showType; private String showType;
private AlertTemplate alertTemplate; private AlertTemplate alertTemplate;
private String mustNotNull = "must not be null";
public MailSender(Map<String, String> config) { public MailSender(Map<String, String> config) {
String receiversConfig = config.get(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS); String receiversConfig = config.get(MailParamsConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS);
if (receiversConfig == null || "".equals(receiversConfig)) { if (receiversConfig == null || "".equals(receiversConfig)) {
throw new RuntimeException(MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS + "must not be null"); throw new AlertEmailException(MailParamsConstants.PLUGIN_DEFAULT_EMAIL_RECEIVERS + mustNotNull);
} }
receivers = Arrays.asList(receiversConfig.split(",")); receivers = Arrays.asList(receiversConfig.split(","));
@ -95,33 +97,33 @@ public class MailSender {
} }
mailSmtpHost = config.get(MailParamsConstants.NAME_MAIL_SMTP_HOST); mailSmtpHost = config.get(MailParamsConstants.NAME_MAIL_SMTP_HOST);
requireNonNull(mailSmtpHost, MailParamsConstants.MAIL_SMTP_HOST + " must not null"); requireNonNull(mailSmtpHost, MailParamsConstants.MAIL_SMTP_HOST + mustNotNull);
mailSmtpPort = config.get(MailParamsConstants.NAME_MAIL_SMTP_PORT); mailSmtpPort = config.get(MailParamsConstants.NAME_MAIL_SMTP_PORT);
requireNonNull(mailSmtpPort, MailParamsConstants.MAIL_SMTP_PORT + " must not null"); requireNonNull(mailSmtpPort, MailParamsConstants.MAIL_SMTP_PORT + mustNotNull);
mailSender = config.get(MailParamsConstants.NAME_MAIL_SENDER); mailSenderEmail = config.get(MailParamsConstants.NAME_MAIL_SENDER);
requireNonNull(mailSender, MailParamsConstants.MAIL_SENDER + " must not null"); requireNonNull(mailSenderEmail, MailParamsConstants.MAIL_SENDER + mustNotNull);
enableSmtpAuth = config.get(MailParamsConstants.NAME_MAIL_SMTP_AUTH); enableSmtpAuth = config.get(MailParamsConstants.NAME_MAIL_SMTP_AUTH);
mailUser = config.get(MailParamsConstants.NAME_MAIL_USER); mailUser = config.get(MailParamsConstants.NAME_MAIL_USER);
requireNonNull(mailUser, MailParamsConstants.MAIL_USER + " must not null"); requireNonNull(mailUser, MailParamsConstants.MAIL_USER + mustNotNull);
mailPasswd = config.get(MailParamsConstants.NAME_MAIL_PASSWD); mailPasswd = config.get(MailParamsConstants.NAME_MAIL_PASSWD);
requireNonNull(mailPasswd, MailParamsConstants.MAIL_PASSWD + " must not null"); requireNonNull(mailPasswd, MailParamsConstants.MAIL_PASSWD + mustNotNull);
mailUseStartTLS = config.get(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE); mailUseStartTLS = config.get(MailParamsConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE);
requireNonNull(mailUseStartTLS, MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE + " must not null"); requireNonNull(mailUseStartTLS, MailParamsConstants.MAIL_SMTP_STARTTLS_ENABLE + mustNotNull);
mailUseSSL = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE); mailUseSSL = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_ENABLE);
requireNonNull(mailUseSSL, MailParamsConstants.MAIL_SMTP_SSL_ENABLE + " must not null"); requireNonNull(mailUseSSL, MailParamsConstants.MAIL_SMTP_SSL_ENABLE + mustNotNull);
sslTrust = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST); sslTrust = config.get(MailParamsConstants.NAME_MAIL_SMTP_SSL_TRUST);
requireNonNull(sslTrust, MailParamsConstants.MAIL_SMTP_SSL_TRUST + " must not null"); requireNonNull(sslTrust, MailParamsConstants.MAIL_SMTP_SSL_TRUST + mustNotNull);
showType = config.get(AlertConstants.SHOW_TYPE); showType = config.get(AlertConstants.SHOW_TYPE);
requireNonNull(showType, AlertConstants.SHOW_TYPE + " must not null"); requireNonNull(showType, AlertConstants.SHOW_TYPE + mustNotNull);
xlsFilePath = config.get(EmailConstants.XLS_FILE_PATH); xlsFilePath = config.get(EmailConstants.XLS_FILE_PATH);
if (StringUtils.isBlank(xlsFilePath)) { if (StringUtils.isBlank(xlsFilePath)) {
@ -136,7 +138,6 @@ public class MailSender {
* *
* @param title title * @param title title
* @param content content * @param content content
* @return
*/ */
public AlertResult sendMails(String title, String content) { public AlertResult sendMails(String title, String content) {
return sendMails(this.receivers, this.receiverCcs, title, content); return sendMails(this.receivers, this.receiverCcs, title, content);
@ -147,7 +148,6 @@ public class MailSender {
* *
* @param title email title * @param title email title
* @param content email content * @param content email content
* @return
*/ */
public AlertResult sendMailsToReceiverOnly(String title, String content) { public AlertResult sendMailsToReceiverOnly(String title, String content) {
return sendMails(this.receivers, null, title, content); return sendMails(this.receivers, null, title, content);
@ -160,7 +160,6 @@ public class MailSender {
* @param receiverCcs receiverCcs * @param receiverCcs receiverCcs
* @param title title * @param title title
* @param content content * @param content content
* @return
*/ */
public AlertResult sendMails(List<String> receivers, List<String> receiverCcs, String title, String content) { public AlertResult sendMails(List<String> receivers, List<String> receiverCcs, String title, String content) {
AlertResult alertResult = new AlertResult(); AlertResult alertResult = new AlertResult();
@ -180,7 +179,7 @@ public class MailSender {
try { try {
Session session = getSession(); Session session = getSession();
email.setMailSession(session); email.setMailSession(session);
email.setFrom(mailSender); email.setFrom(mailSenderEmail);
email.setCharset(EmailConstants.UTF_8); email.setCharset(EmailConstants.UTF_8);
if (CollectionUtils.isNotEmpty(receivers)) { if (CollectionUtils.isNotEmpty(receivers)) {
// receivers mail // receivers mail
@ -251,11 +250,6 @@ public class MailSender {
/** /**
* send mail as Excel attachment * send mail as Excel attachment
*
* @param title
* @param content
* @param partContent
* @throws Exception
*/ */
private void attachment(String title, String content, String partContent) throws Exception { private void attachment(String title, String content, String partContent) throws Exception {
MimeMessage msg = getMimeMessage(); MimeMessage msg = getMimeMessage();
@ -265,9 +259,6 @@ public class MailSender {
/** /**
* get MimeMessage * get MimeMessage
*
* @return
* @throws MessagingException
*/ */
private MimeMessage getMimeMessage() throws MessagingException { private MimeMessage getMimeMessage() throws MessagingException {
@ -279,7 +270,7 @@ public class MailSender {
// 2. creating mail: Creating a MimeMessage // 2. creating mail: Creating a MimeMessage
MimeMessage msg = new MimeMessage(session); MimeMessage msg = new MimeMessage(session);
// 3. set sender // 3. set sender
msg.setFrom(new InternetAddress(mailSender)); msg.setFrom(new InternetAddress(mailSenderEmail));
// 4. set receivers // 4. set receivers
for (String receiver : receivers) { for (String receiver : receivers) {
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver));
@ -317,16 +308,9 @@ public class MailSender {
/** /**
* attach content * attach content
*
* @param title
* @param content
* @param partContent
* @param msg
* @throws MessagingException
* @throws IOException
*/ */
private void attachContent(String title, String content, String partContent, MimeMessage msg) throws MessagingException, IOException { private void attachContent(String title, String content, String partContent, MimeMessage msg) throws MessagingException, IOException {
/** /*
* set receiverCc * set receiverCc
*/ */
if (CollectionUtils.isNotEmpty(receiverCcs)) { if (CollectionUtils.isNotEmpty(receiverCcs)) {
@ -365,21 +349,14 @@ public class MailSender {
/** /**
* the string object map * the string object map
*
* @param title
* @param content
* @param alertResult
* @param email
* @return
* @throws EmailException
*/ */
private AlertResult getStringObjectMap(String title, String content, AlertResult alertResult, HtmlEmail email) throws EmailException { private AlertResult getStringObjectMap(String title, String content, AlertResult alertResult, HtmlEmail email) throws EmailException {
/** /*
* the subject of the message to be sent * the subject of the message to be sent
*/ */
email.setSubject(title); email.setSubject(title);
/** /*
* to send information, you can use HTML tags in mail content because of the use of HtmlEmail * to send information, you can use HTML tags in mail content because of the use of HtmlEmail
*/ */
if (showType.equals(ShowType.TABLE.getDescp())) { if (showType.equals(ShowType.TABLE.getDescp())) {
@ -417,9 +394,6 @@ public class MailSender {
/** /**
* handle exception * handle exception
*
* @param alertResult
* @param e
*/ */
private void handleException(AlertResult alertResult, Exception e) { private void handleException(AlertResult alertResult, Exception e) {
logger.error("Send email to {} failed", receivers, e); logger.error("Send email to {} failed", receivers, e);

40
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/exception/AlertEmailException.java

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.plugin.alert.email.exception;
public class AlertEmailException extends RuntimeException {
/**
* Create Runtime exception
*
* @param errMsg - Error message
*/
public AlertEmailException(String errMsg) {
super(errMsg);
}
/**
* Create Runtime exception
*
* @param errMsg - Error message
* @param cause - cause
*/
public AlertEmailException(String errMsg, Throwable cause) {
super(errMsg, cause);
}
}

9
dolphinscheduler-alert-plugin/dolphinscheduler-alert-email/src/main/java/org/apache/dolphinscheduler/plugin/alert/email/template/DefaultHTMLTemplate.java

@ -50,7 +50,7 @@ public class DefaultHTMLTemplate implements AlertTemplate {
case TABLE: case TABLE:
return getTableTypeMessage(content, showAll); return getTableTypeMessage(content, showAll);
case TEXT: case TEXT:
return getTextTypeMessage(content, showAll); return getTextTypeMessage(content);
default: default:
throw new IllegalArgumentException(String.format("not support showType: %s in DefaultHTMLTemplate", showType)); throw new IllegalArgumentException(String.format("not support showType: %s in DefaultHTMLTemplate", showType));
} }
@ -77,7 +77,7 @@ public class DefaultHTMLTemplate implements AlertTemplate {
boolean flag = true; boolean flag = true;
String title = ""; String title = "";
for (LinkedHashMap mapItems : mapItemsList) { for (LinkedHashMap<String, Object> mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet(); Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
@ -111,10 +111,9 @@ public class DefaultHTMLTemplate implements AlertTemplate {
* get alert message which type is TEXT * get alert message which type is TEXT
* *
* @param content message content * @param content message content
* @param showAll weather to show all
* @return alert message * @return alert message
*/ */
private String getTextTypeMessage(String content, boolean showAll) { private String getTextTypeMessage(String content) {
if (StringUtils.isNotEmpty(content)) { if (StringUtils.isNotEmpty(content)) {
ArrayNode list = JSONUtils.parseArray(content); ArrayNode list = JSONUtils.parseArray(content);
@ -142,7 +141,7 @@ public class DefaultHTMLTemplate implements AlertTemplate {
private String getMessageFromHtmlTemplate(String title, String content) { private String getMessageFromHtmlTemplate(String title, String content) {
requireNonNull(content, "content must not null"); requireNonNull(content, "content must not null");
String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>\n", title); String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>%n", title);
return EmailConstants.HTML_HEADER_PREFIX + htmlTableThead + content + EmailConstants.TABLE_BODY_HTML_TAIL; return EmailConstants.HTML_HEADER_PREFIX + htmlTableThead + content + EmailConstants.TABLE_BODY_HTML_TAIL;
} }

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/OSUtils.java

@ -22,7 +22,7 @@ package org.apache.dolphinscheduler.plugin.alert.script;
*/ */
public class OSUtils { public class OSUtils {
public OSUtils() { private OSUtils() {
throw new UnsupportedOperationException("Construct OSUtils"); throw new UnsupportedOperationException("Construct OSUtils");
} }

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/ScriptParamsConstants.java

@ -22,7 +22,7 @@ package org.apache.dolphinscheduler.plugin.alert.script;
*/ */
public class ScriptParamsConstants { public class ScriptParamsConstants {
public ScriptParamsConstants() { private ScriptParamsConstants() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }

2
dolphinscheduler-alert-plugin/dolphinscheduler-alert-script/src/main/java/org/apache/dolphinscheduler/plugin/alert/script/StreamGobbler.java

@ -51,7 +51,7 @@ public class StreamGobbler extends Thread {
output.append(System.getProperty("line.separator")); output.append(System.getProperty("line.separator"));
} }
if (output.length() > 0) { if (output.length() > 0) {
logger.info("out put msg is{}",output.toString()); logger.info("out put msg is{}", output);
} }
} catch (IOException e) { } catch (IOException e) {
logger.error("I/O error occurs {}", e.getMessage()); logger.error("I/O error occurs {}", e.getMessage());

4
dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertConstants.java

@ -22,6 +22,10 @@ package org.apache.dolphinscheduler.plugin.alert.wechat;
*/ */
public class WeChatAlertConstants { public class WeChatAlertConstants {
private WeChatAlertConstants() {
throw new IllegalStateException(WeChatAlertConstants.class.getName());
}
static final String MARKDOWN_QUOTE = ">"; static final String MARKDOWN_QUOTE = ">";
static final String MARKDOWN_ENTER = "\n"; static final String MARKDOWN_ENTER = "\n";

3
dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatAlertParamsConstants.java

@ -22,6 +22,9 @@ package org.apache.dolphinscheduler.plugin.alert.wechat;
*/ */
public class WeChatAlertParamsConstants { public class WeChatAlertParamsConstants {
private WeChatAlertParamsConstants() {
throw new IllegalStateException(WeChatAlertParamsConstants.class.getName());
}
static final String ENTERPRISE_WE_CHAT_CORP_ID = "corp.id"; static final String ENTERPRISE_WE_CHAT_CORP_ID = "corp.id";

47
dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/WeChatSender.java

@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.plugin.alert.wechat;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import org.apache.dolphinscheduler.plugin.alert.wechat.exception.WeChatAlertException;
import org.apache.dolphinscheduler.spi.alert.AlertConstants; import org.apache.dolphinscheduler.spi.alert.AlertConstants;
import org.apache.dolphinscheduler.spi.alert.AlertResult; import org.apache.dolphinscheduler.spi.alert.AlertResult;
import org.apache.dolphinscheduler.spi.alert.ShowType; import org.apache.dolphinscheduler.spi.alert.ShowType;
@ -59,8 +60,6 @@ public class WeChatSender {
private String weChatUsers; private String weChatUsers;
private String weChatTeamSendMsg;
private String weChatUserSendMsg; private String weChatUserSendMsg;
private String weChatTokenUrlReplace; private String weChatTokenUrlReplace;
@ -70,14 +69,14 @@ public class WeChatSender {
private String showType; private String showType;
private static final String agentIdRegExp = "{agentId}"; private static final String MUST_NOT_NULL = " must not null";
private static final String msgRegExp = "{msg}"; private static final String ALERT_STATUS = "false";
private static final String userRegExp = "{toUser}"; private static final String AGENT_ID_REG_EXP = "{agentId}";
private static final String corpIdRegex = "{corpId}"; private static final String MSG_REG_EXP = "{msg}";
private static final String secretRegex = "{secret}"; private static final String USER_REG_EXP = "{toUser}";
private static final String toPartyRegex = "{toParty}"; private static final String CORP_ID_REGEX = "{corpId}";
private static final String toUserRegex = "{toUser}"; private static final String SECRET_REGEX = "{secret}";
private static final String tokenRegex = "{token}"; private static final String TOKEN_REGEX = "{token}";
WeChatSender(Map<String, String> config) { WeChatSender(Map<String, String> config) {
weChatAgentId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID); weChatAgentId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_AGENT_ID);
@ -85,13 +84,12 @@ public class WeChatSender {
String weChatCorpId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID); String weChatCorpId = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_CORP_ID);
String weChatSecret = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET); String weChatSecret = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_SECRET);
String weChatTokenUrl = WeChatAlertConstants.WE_CHAT_TOKEN_URL; String weChatTokenUrl = WeChatAlertConstants.WE_CHAT_TOKEN_URL;
weChatTeamSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_TEAM_SEND_MSG);
weChatUserSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG); weChatUserSendMsg = config.get(WeChatAlertParamsConstants.NAME_ENTERPRISE_WE_CHAT_USER_SEND_MSG);
showType = config.get(AlertConstants.SHOW_TYPE); showType = config.get(AlertConstants.SHOW_TYPE);
requireNonNull(showType, AlertConstants.SHOW_TYPE + " must not null"); requireNonNull(showType, AlertConstants.SHOW_TYPE + MUST_NOT_NULL);
weChatTokenUrlReplace = weChatTokenUrl weChatTokenUrlReplace = weChatTokenUrl
.replace(corpIdRegex, weChatCorpId) .replace(CORP_ID_REGEX, weChatCorpId)
.replace(secretRegex, weChatSecret); .replace(SECRET_REGEX, weChatSecret);
weChatToken = getToken(); weChatToken = getToken();
} }
@ -105,16 +103,15 @@ public class WeChatSender {
*/ */
private String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) { private String makeUserSendMsg(Collection<String> toUser, String agentId, String msg) {
String listUser = mkString(toUser); String listUser = mkString(toUser);
return weChatUserSendMsg.replace(userRegExp, listUser) return weChatUserSendMsg.replace(USER_REG_EXP, listUser)
.replace(agentIdRegExp, agentId) .replace(AGENT_ID_REG_EXP, agentId)
.replace(msgRegExp, msg); .replace(MSG_REG_EXP, msg);
} }
/** /**
* send Enterprise WeChat * send Enterprise WeChat
* *
* @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""} * @return Enterprise WeChat resp, demo: {"errcode":0,"errmsg":"ok","invaliduser":""}
* @throws Exception the Exception
*/ */
public AlertResult sendEnterpriseWeChat(String title, String content) { public AlertResult sendEnterpriseWeChat(String title, String content) {
AlertResult alertResult; AlertResult alertResult;
@ -124,10 +121,10 @@ public class WeChatSender {
if (null == weChatToken) { if (null == weChatToken) {
alertResult = new AlertResult(); alertResult = new AlertResult();
alertResult.setMessage("send we chat alert fail,get weChat token error"); alertResult.setMessage("send we chat alert fail,get weChat token error");
alertResult.setStatus("false"); alertResult.setStatus(ALERT_STATUS);
return alertResult; return alertResult;
} }
String enterpriseWeChatPushUrlReplace = WeChatAlertConstants.WE_CHAT_PUSH_URL.replace(tokenRegex, weChatToken); String enterpriseWeChatPushUrlReplace = WeChatAlertConstants.WE_CHAT_PUSH_URL.replace(TOKEN_REGEX, weChatToken);
try { try {
return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg)); return checkWeChatSendMsgResult(post(enterpriseWeChatPushUrlReplace, msg));
@ -135,7 +132,7 @@ public class WeChatSender {
logger.info("send we chat alert msg exception : {}", e.getMessage()); logger.info("send we chat alert msg exception : {}", e.getMessage());
alertResult = new AlertResult(); alertResult = new AlertResult();
alertResult.setMessage("send we chat alert fail"); alertResult.setMessage("send we chat alert fail");
alertResult.setStatus("false"); alertResult.setStatus(ALERT_STATUS);
} }
return alertResult; return alertResult;
} }
@ -170,7 +167,7 @@ public class WeChatSender {
List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class); List<LinkedHashMap> mapItemsList = JSONUtils.toList(content, LinkedHashMap.class);
if (null == mapItemsList || mapItemsList.isEmpty()) { if (null == mapItemsList || mapItemsList.isEmpty()) {
logger.error("itemsList is null"); logger.error("itemsList is null");
throw new RuntimeException("itemsList is null"); throw new WeChatAlertException("itemsList is null");
} }
StringBuilder contents = new StringBuilder(200); StringBuilder contents = new StringBuilder(200);
for (LinkedHashMap mapItems : mapItemsList) { for (LinkedHashMap mapItems : mapItemsList) {
@ -259,7 +256,7 @@ public class WeChatSender {
EntityUtils.consume(entity); EntityUtils.consume(entity);
} }
HashMap map = JSONUtils.parseObject(resp, HashMap.class); HashMap<String, Object> map = JSONUtils.parseObject(resp, HashMap.class);
if (map != null && null != map.get("access_token")) { if (map != null && null != map.get("access_token")) {
return map.get("access_token").toString(); return map.get("access_token").toString();
} else { } else {
@ -310,7 +307,7 @@ public class WeChatSender {
private static AlertResult checkWeChatSendMsgResult(String result) { private static AlertResult checkWeChatSendMsgResult(String result) {
AlertResult alertResult = new AlertResult(); AlertResult alertResult = new AlertResult();
alertResult.setStatus("false"); alertResult.setStatus(ALERT_STATUS);
if (null == result) { if (null == result) {
alertResult.setMessage("we chat send fail"); alertResult.setMessage("we chat send fail");
@ -328,7 +325,7 @@ public class WeChatSender {
alertResult.setMessage("we chat alert send success"); alertResult.setMessage("we chat alert send success");
return alertResult; return alertResult;
} }
alertResult.setStatus("false"); alertResult.setStatus(ALERT_STATUS);
alertResult.setMessage(sendMsgResponse.getErrmsg()); alertResult.setMessage(sendMsgResponse.getErrmsg());
return alertResult; return alertResult;
} }

30
dolphinscheduler-alert-plugin/dolphinscheduler-alert-wechat/src/main/java/org/apache/dolphinscheduler/plugin/alert/wechat/exception/WeChatAlertException.java

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.plugin.alert.wechat.exception;
public class WeChatAlertException extends RuntimeException {
/**
* Create Runtime Exception
*
* @param errMsg - Error message
*/
public WeChatAlertException(String errMsg) {
super(errMsg);
}
}

32
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java

@ -17,17 +17,20 @@
package org.apache.dolphinscheduler.api.configuration; package org.apache.dolphinscheduler.api.configuration;
import org.apache.dolphinscheduler.api.interceptor.LocaleChangeInterceptor;
import org.apache.dolphinscheduler.api.interceptor.LoginHandlerInterceptor; import org.apache.dolphinscheduler.api.interceptor.LoginHandlerInterceptor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import java.util.Locale; import java.util.Locale;
/** /**
* application configuration * application configuration
*/ */
@ -39,7 +42,17 @@ public class AppConfiguration implements WebMvcConfigurer {
public static final String REGISTER_PATH_PATTERN = "/users/register"; public static final String REGISTER_PATH_PATTERN = "/users/register";
public static final String PATH_PATTERN = "/**"; public static final String PATH_PATTERN = "/**";
public static final String LOCALE_LANGUAGE_COOKIE = "language"; public static final String LOCALE_LANGUAGE_COOKIE = "language";
public static final int COOKIE_MAX_AGE = 3600;
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration(PATH_PATTERN, config);
return new CorsFilter(configSource);
}
@Bean @Bean
public LoginHandlerInterceptor loginInterceptor() { public LoginHandlerInterceptor loginInterceptor() {
@ -56,16 +69,14 @@ public class AppConfiguration implements WebMvcConfigurer {
localeResolver.setCookieName(LOCALE_LANGUAGE_COOKIE); localeResolver.setCookieName(LOCALE_LANGUAGE_COOKIE);
// set default locale // set default locale
localeResolver.setDefaultLocale(Locale.US); localeResolver.setDefaultLocale(Locale.US);
// set cookie max age // set language tag compliant
localeResolver.setCookieMaxAge(COOKIE_MAX_AGE); localeResolver.setLanguageTagCompliant(false);
return localeResolver; return localeResolver;
} }
@Bean @Bean
public LocaleChangeInterceptor localeChangeInterceptor() { public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); return new LocaleChangeInterceptor();
lci.setParamName("language");
return lci;
} }
@Override @Override
@ -94,11 +105,6 @@ public class AppConfiguration implements WebMvcConfigurer {
registry.addViewController("/").setViewName("forward:/ui/index.html"); registry.addViewController("/").setViewName("forward:/ui/index.html");
} }
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping(PATH_PATTERN).allowedOrigins("*").allowedMethods("*");
}
/** /**
* Turn off suffix-based content negotiation * Turn off suffix-based content negotiation
* *

15
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java

@ -40,6 +40,7 @@ import org.apache.dolphinscheduler.api.service.ProcessDefinitionService;
import org.apache.dolphinscheduler.api.service.ProcessDefinitionVersionService; import org.apache.dolphinscheduler.api.service.ProcessDefinitionVersionService;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.utils.ParameterUtils; import org.apache.dolphinscheduler.common.utils.ParameterUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils; import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
@ -239,7 +240,7 @@ public class ProcessDefinitionController extends BaseController {
@ApiImplicitParam(name = "locations", value = "PROCESS_DEFINITION_LOCATIONS", required = true, type = "String"), @ApiImplicitParam(name = "locations", value = "PROCESS_DEFINITION_LOCATIONS", required = true, type = "String"),
@ApiImplicitParam(name = "connects", value = "PROCESS_DEFINITION_CONNECTS", required = true, type = "String"), @ApiImplicitParam(name = "connects", value = "PROCESS_DEFINITION_CONNECTS", required = true, type = "String"),
@ApiImplicitParam(name = "description", value = "PROCESS_DEFINITION_DESC", required = false, type = "String"), @ApiImplicitParam(name = "description", value = "PROCESS_DEFINITION_DESC", required = false, type = "String"),
@ApiImplicitParam(name = "releaseState", value = "RELEASE_PROCESS_DEFINITION_NOTES", required = false, dataType = "Int", example = "0") @ApiImplicitParam(name = "releaseState", value = "RELEASE_PROCESS_DEFINITION_NOTES", required = false, dataType = "ReleaseState")
}) })
@PostMapping(value = "/update") @PostMapping(value = "/update")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@ -252,7 +253,7 @@ public class ProcessDefinitionController extends BaseController {
@RequestParam(value = "locations", required = false) String locations, @RequestParam(value = "locations", required = false) String locations,
@RequestParam(value = "connects", required = false) String connects, @RequestParam(value = "connects", required = false) String connects,
@RequestParam(value = "description", required = false) String description, @RequestParam(value = "description", required = false) String description,
@RequestParam(value = "releaseState", required = false, defaultValue = "0") int releaseState) { @RequestParam(value = "releaseState", required = false, defaultValue = "OFFLINE") ReleaseState releaseState) {
logger.info("login user {}, update process define, project name: {}, process define name: {}, " logger.info("login user {}, update process define, project name: {}, process define name: {}, "
+ "process_definition_json: {}, desc: {}, locations:{}, connects:{}", + "process_definition_json: {}, desc: {}, locations:{}, connects:{}",
@ -260,12 +261,12 @@ public class ProcessDefinitionController extends BaseController {
Map<String, Object> result = processDefinitionService.updateProcessDefinition(loginUser, projectName, id, name, Map<String, Object> result = processDefinitionService.updateProcessDefinition(loginUser, projectName, id, name,
processDefinitionJson, description, locations, connects); processDefinitionJson, description, locations, connects);
// If the update fails, the result will be returned directly // If the update fails, the result will be returned directly
Status status = (Status) result.get("status"); if (result.get(Constants.STATUS) != Status.SUCCESS) {
if (status.getCode() != 0) {
return returnDataList(result); return returnDataList(result);
} }
// Judge whether to go online after editing,0 means offline, 1 means online // Judge whether to go online after editing,0 means offline, 1 means online
if (releaseState == 1) { if (releaseState == ReleaseState.ONLINE) {
result = processDefinitionService.releaseProcessDefinition(loginUser, projectName, id, releaseState); result = processDefinitionService.releaseProcessDefinition(loginUser, projectName, id, releaseState);
} }
return returnDataList(result); return returnDataList(result);
@ -367,7 +368,7 @@ public class ProcessDefinitionController extends BaseController {
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String"), @ApiImplicitParam(name = "name", value = "PROCESS_DEFINITION_NAME", required = true, type = "String"),
@ApiImplicitParam(name = "processId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"), @ApiImplicitParam(name = "processId", value = "PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
@ApiImplicitParam(name = "releaseState", value = "PROCESS_DEFINITION_CONNECTS", required = true, dataType = "Int", example = "100"), @ApiImplicitParam(name = "releaseState", value = "PROCESS_DEFINITION_CONNECTS", required = true, dataType = "ReleaseState"),
}) })
@PostMapping(value = "/release") @PostMapping(value = "/release")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@ -375,7 +376,7 @@ public class ProcessDefinitionController extends BaseController {
public Result releaseProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, public Result releaseProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName, @ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
@RequestParam(value = "processId", required = true) int processId, @RequestParam(value = "processId", required = true) int processId,
@RequestParam(value = "releaseState", required = true) int releaseState) { @RequestParam(value = "releaseState", required = true) ReleaseState releaseState) {
logger.info("login user {}, release process definition, project name: {}, release state: {}", logger.info("login user {}, release process definition, project name: {}, release state: {}",
loginUser.getUserName(), projectName, releaseState); loginUser.getUserName(), projectName, releaseState);

56
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptor.java

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.interceptor;
import org.apache.dolphinscheduler.api.service.BaseService;
import org.apache.dolphinscheduler.common.Constants;
import java.util.Locale;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class LocaleChangeInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
Cookie cookie = BaseService.getCookie(request, Constants.LOCALE_LANGUAGE);
if (cookie != null) {
// Proceed in cookie
return true;
}
// Proceed in header
String newLocale = request.getHeader(Constants.LOCALE_LANGUAGE);
if (newLocale != null) {
LocaleContextHolder.setLocale(parseLocaleValue(newLocale));
}
return true;
}
@Nullable
protected Locale parseLocaleValue(String localeValue) {
return StringUtils.parseLocale(localeValue);
}
}

3
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.service; package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.dao.entity.ProcessData; import org.apache.dolphinscheduler.dao.entity.ProcessData;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
@ -190,7 +191,7 @@ public interface ProcessDefinitionService {
Map<String, Object> releaseProcessDefinition(User loginUser, Map<String, Object> releaseProcessDefinition(User loginUser,
String projectName, String projectName,
int id, int id,
int releaseState); ReleaseState releaseState);
/** /**
* batch export process definition by ids * batch export process definition by ids

12
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java

@ -583,7 +583,7 @@ public class ProcessDefinitionServiceImpl extends BaseService implements
*/ */
@Override @Override
@Transactional(rollbackFor = RuntimeException.class) @Transactional(rollbackFor = RuntimeException.class)
public Map<String, Object> releaseProcessDefinition(User loginUser, String projectName, int id, int releaseState) { public Map<String, Object> releaseProcessDefinition(User loginUser, String projectName, int id, ReleaseState releaseState) {
HashMap<String, Object> result = new HashMap<>(); HashMap<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName); Project project = projectMapper.queryByName(projectName);
@ -593,17 +593,15 @@ public class ProcessDefinitionServiceImpl extends BaseService implements
return checkResult; return checkResult;
} }
ReleaseState state = ReleaseState.getEnum(releaseState);
// check state // check state
if (null == state) { if (null == releaseState) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, RELEASESTATE); putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, RELEASESTATE);
return result; return result;
} }
ProcessDefinition processDefinition = processDefineMapper.selectById(id); ProcessDefinition processDefinition = processDefineMapper.selectById(id);
switch (state) { switch (releaseState) {
case ONLINE: case ONLINE:
// To check resources whether they are already cancel authorized or deleted // To check resources whether they are already cancel authorized or deleted
String resourceIds = processDefinition.getResourceIds(); String resourceIds = processDefinition.getResourceIds();
@ -619,11 +617,11 @@ public class ProcessDefinitionServiceImpl extends BaseService implements
} }
} }
processDefinition.setReleaseState(state); processDefinition.setReleaseState(releaseState);
processDefineMapper.updateById(processDefinition); processDefineMapper.updateById(processDefinition);
break; break;
case OFFLINE: case OFFLINE:
processDefinition.setReleaseState(state); processDefinition.setReleaseState(releaseState);
processDefineMapper.updateById(processDefinition); processDefineMapper.updateById(processDefinition);
List<Schedule> scheduleList = scheduleMapper.selectAllByProcessDefineArray( List<Schedule> scheduleList = scheduleMapper.selectAllByProcessDefineArray(
new int[]{processDefinition.getId()} new int[]{processDefinition.getId()}

21
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java

@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.PageInfo; import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.ProjectUser; import org.apache.dolphinscheduler.dao.entity.ProjectUser;
@ -442,21 +443,13 @@ public class ProjectServiceImpl extends BaseService implements ProjectService {
*/ */
public Map<String, Object> queryAllProjectList() { public Map<String, Object> queryAllProjectList() {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
List<Project> projects = projectMapper.selectList(null); List<Project> projects = new ArrayList<>();
List<ProcessDefinition> processDefinitions = processDefinitionMapper.selectList(null);
if (projects != null) { List<Integer> projectIds = processDefinitionMapper.listProjectIds();
Set<Integer> set = new HashSet<>(); if (CollectionUtils.isNotEmpty(projectIds)) {
for (ProcessDefinition processDefinition : processDefinitions) { projects = projectMapper.selectBatchIds(projectIds);
set.add(processDefinition.getProjectId());
}
List<Project> tempDeletelist = new ArrayList<>();
for (Project project : projects) {
if (!set.contains(project.getId())) {
tempDeletelist.add(project);
}
}
projects.removeAll(tempDeletelist);
} }
result.put(Constants.DATA_LIST, projects); result.put(Constants.DATA_LIST, projects);
putMsg(result, Status.SUCCESS); putMsg(result, Status.SUCCESS);
return result; return result;

7
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java

@ -142,7 +142,6 @@ public class ProcessDefinitionControllerTest {
String description = "desc test"; String description = "desc test";
String connects = "[]"; String connects = "[]";
int id = 1; int id = 1;
int releaseState = 0;
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS); putMsg(result, Status.SUCCESS);
result.put("processDefinitionId", 1); result.put("processDefinitionId", 1);
@ -151,7 +150,7 @@ public class ProcessDefinitionControllerTest {
description, locations, connects)).thenReturn(result); description, locations, connects)).thenReturn(result);
Result response = processDefinitionController.updateProcessDefinition(user, projectName, name, id, json, Result response = processDefinitionController.updateProcessDefinition(user, projectName, name, id, json,
locations, connects, description,releaseState); locations, connects, description,ReleaseState.OFFLINE);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue()); Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
} }
@ -162,8 +161,8 @@ public class ProcessDefinitionControllerTest {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS); putMsg(result, Status.SUCCESS);
Mockito.when(processDefinitionService.releaseProcessDefinition(user, projectName, id, ReleaseState.OFFLINE.ordinal())).thenReturn(result); Mockito.when(processDefinitionService.releaseProcessDefinition(user, projectName, id, ReleaseState.OFFLINE)).thenReturn(result);
Result response = processDefinitionController.releaseProcessDefinition(user, projectName, id, ReleaseState.OFFLINE.ordinal()); Result response = processDefinitionController.releaseProcessDefinition(user, projectName, id, ReleaseState.OFFLINE);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue()); Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
} }

48
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptorTest.java

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.interceptor;
import org.apache.dolphinscheduler.api.ApiApplicationServer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApiApplicationServer.class)
public class LocaleChangeInterceptorTest {
@Autowired
LocaleChangeInterceptor interceptor;
@Test
public void testPreHandle() {
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
// test no language
Assert.assertTrue(interceptor.preHandle(request, response, null));
}
}

8
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java

@ -592,14 +592,14 @@ public class ProcessDefinitionServiceTest {
putMsg(result, Status.PROJECT_NOT_FOUNT, projectName); putMsg(result, Status.PROJECT_NOT_FOUNT, projectName);
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result); Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
Map<String, Object> map = processDefinitionService.releaseProcessDefinition(loginUser, "project_test1", Map<String, Object> map = processDefinitionService.releaseProcessDefinition(loginUser, "project_test1",
6, ReleaseState.OFFLINE.getCode()); 6, ReleaseState.OFFLINE);
Assert.assertEquals(Status.PROJECT_NOT_FOUNT, map.get(Constants.STATUS)); Assert.assertEquals(Status.PROJECT_NOT_FOUNT, map.get(Constants.STATUS));
// project check auth success, processs definition online // project check auth success, processs definition online
putMsg(result, Status.SUCCESS, projectName); putMsg(result, Status.SUCCESS, projectName);
Mockito.when(processDefineMapper.selectById(46)).thenReturn(getProcessDefinition()); Mockito.when(processDefineMapper.selectById(46)).thenReturn(getProcessDefinition());
Map<String, Object> onlineRes = processDefinitionService.releaseProcessDefinition( Map<String, Object> onlineRes = processDefinitionService.releaseProcessDefinition(
loginUser, "project_test1", 46, ReleaseState.ONLINE.getCode()); loginUser, "project_test1", 46, ReleaseState.ONLINE);
Assert.assertEquals(Status.SUCCESS, onlineRes.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, onlineRes.get(Constants.STATUS));
// project check auth success, processs definition online // project check auth success, processs definition online
@ -608,12 +608,12 @@ public class ProcessDefinitionServiceTest {
Mockito.when(processDefineMapper.selectById(46)).thenReturn(processDefinition1); Mockito.when(processDefineMapper.selectById(46)).thenReturn(processDefinition1);
Mockito.when(processService.getUserById(1)).thenReturn(loginUser); Mockito.when(processService.getUserById(1)).thenReturn(loginUser);
Map<String, Object> onlineWithResourceRes = processDefinitionService.releaseProcessDefinition( Map<String, Object> onlineWithResourceRes = processDefinitionService.releaseProcessDefinition(
loginUser, "project_test1", 46, ReleaseState.ONLINE.getCode()); loginUser, "project_test1", 46, ReleaseState.ONLINE);
Assert.assertEquals(Status.SUCCESS, onlineWithResourceRes.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, onlineWithResourceRes.get(Constants.STATUS));
// release error code // release error code
Map<String, Object> failRes = processDefinitionService.releaseProcessDefinition( Map<String, Object> failRes = processDefinitionService.releaseProcessDefinition(
loginUser, "project_test1", 46, 2); loginUser, "project_test1", 46, ReleaseState.getEnum(2));
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, failRes.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, failRes.get(Constants.STATUS));
//FIXME has function exit code 1 when exception //FIXME has function exit code 1 when exception

11
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java

@ -32,6 +32,7 @@ import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper; import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -319,9 +320,8 @@ public class ProjectServiceTest {
@Test @Test
public void testQueryAllProjectList() { public void testQueryAllProjectList() {
Mockito.when(processDefinitionMapper.listProjectIds()).thenReturn(getProjectIds());
Mockito.when(projectMapper.selectList(null)).thenReturn(getList()); Mockito.when(projectMapper.selectBatchIds(getProjectIds())).thenReturn(getList());
Mockito.when(processDefinitionMapper.selectList(null)).thenReturn(getProcessDefinitions());
Map<String, Object> result = projectService.queryAllProjectList(); Map<String, Object> result = projectService.queryAllProjectList();
logger.info(result.toString()); logger.info(result.toString());
@ -387,6 +387,11 @@ public class ProjectServiceTest {
return list; return list;
} }
private List<Integer> getProjectIds() {
return Collections.singletonList(1);
}
private String getDesc() { private String getDesc() {
return "projectUserMapper.deleteProjectRelation(projectId,userId)projectUserMappe" return "projectUserMapper.deleteProjectRelation(projectId,userId)projectUserMappe"
+ ".deleteProjectRelation(projectId,userId)projectUserMappe" + ".deleteProjectRelation(projectId,userId)projectUserMappe"

5
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java

@ -906,6 +906,11 @@ public final class Constants {
public static final String PASSWORD_DEFAULT = "******"; public static final String PASSWORD_DEFAULT = "******";
/**
* locale
*/
public static final String LOCALE_LANGUAGE = "language";
/** /**
* driver * driver
*/ */

6
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/CollectionUtils.java

@ -263,13 +263,13 @@ public class CollectionUtils {
} }
Map<String, Object> instanceMap; Map<String, Object> instanceMap;
for (T instance : originList) { for (T instance : originList) {
Map<String, Object> dataMap = new BeanMap(instance); BeanMap beanMap = new BeanMap(instance);
instanceMap = new LinkedHashMap<>(16, 0.75f, true); instanceMap = new LinkedHashMap<>(16, 0.75f, true);
for (Map.Entry<String, Object> entry : dataMap.entrySet()) { for (Map.Entry<Object, Object> entry : beanMap.entrySet()) {
if (exclusionSet.contains(entry.getKey())) { if (exclusionSet.contains(entry.getKey())) {
continue; continue;
} }
instanceMap.put(entry.getKey(), entry.getValue()); instanceMap.put((String) entry.getKey(), entry.getValue());
} }
instanceList.add(instanceMap); instanceList.add(instanceMap);
} }

11
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/OSUtils.java

@ -22,6 +22,7 @@ import org.apache.dolphinscheduler.common.shell.ShellExecutor;
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.Configuration;
import java.lang.management.OperatingSystemMXBean;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -130,11 +131,17 @@ public class OSUtils {
* @return load average * @return load average
*/ */
public static double loadAverage() { public static double loadAverage() {
double loadAverage = hal.getProcessor().getSystemLoadAverage(); double loadAverage;
try {
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
loadAverage = osBean.getSystemLoadAverage();
} catch (Exception e) {
logger.error("get operation system load average exception, try another method ", e);
loadAverage = hal.getProcessor().getSystemLoadAverage();
if (Double.isNaN(loadAverage)) { if (Double.isNaN(loadAverage)) {
return NEGATIVE_ONE; return NEGATIVE_ONE;
} }
}
DecimalFormat df = new DecimalFormat(TWO_DECIMAL); DecimalFormat df = new DecimalFormat(TWO_DECIMAL);
df.setRoundingMode(RoundingMode.HALF_UP); df.setRoundingMode(RoundingMode.HALF_UP);
return Double.parseDouble(df.format(loadAverage)); return Double.parseDouble(df.format(loadAverage));

6
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapper.java

@ -138,4 +138,10 @@ public interface ProcessDefinitionMapper extends BaseMapper<ProcessDefinition> {
* @param version version * @param version version
*/ */
void updateVersionByProcessDefinitionId(@Param("processDefinitionId") int processDefinitionId, @Param("version") long version); void updateVersionByProcessDefinitionId(@Param("processDefinitionId") int processDefinitionId, @Param("version") long version);
/**
* list all project ids
* @return project ids list
*/
List<Integer> listProjectIds();
} }

6
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapper.xml

@ -128,6 +128,12 @@
WHERE user_id = #{userId} and release_state = 1 and resource_ids is not null and resource_ids != '' WHERE user_id = #{userId} and release_state = 1 and resource_ids is not null and resource_ids != ''
</select> </select>
<select id="listProjectIds" resultType="java.lang.Integer">
SELECT DISTINCT(project_id) as project_id
FROM t_ds_process_definition
</select>
<update id="updateVersionByProcessDefinitionId"> <update id="updateVersionByProcessDefinitionId">
update t_ds_process_definition update t_ds_process_definition
set version = #{version} set version = #{version}

8
dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ProcessDefinitionMapperTest.java

@ -366,4 +366,12 @@ public class ProcessDefinitionMapperTest {
ProcessDefinition processDefinition1 = processDefinitionMapper.selectById(processDefinition.getId()); ProcessDefinition processDefinition1 = processDefinitionMapper.selectById(processDefinition.getId());
Assert.assertEquals(expectedVersion, processDefinition1.getVersion()); Assert.assertEquals(expectedVersion, processDefinition1.getVersion());
} }
@Test
public void listProjectIds() {
ProcessDefinition processDefinition = insertOne();
List<Integer> projectIds = processDefinitionMapper.listProjectIds();
Assert.assertNotNull(projectIds);
}
} }

2
dolphinscheduler-dist/release-docs/LICENSE vendored

@ -227,7 +227,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
byte-buddy 1.9.10: https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy/1.9.10, Apache 2.0 byte-buddy 1.9.10: https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy/1.9.10, Apache 2.0
classmate 1.4.0: https://mvnrepository.com/artifact/com.fasterxml/classmate/1.4.0, Apache 2.0 classmate 1.4.0: https://mvnrepository.com/artifact/com.fasterxml/classmate/1.4.0, Apache 2.0
clickhouse-jdbc 0.1.52: https://mvnrepository.com/artifact/ru.yandex.clickhouse/clickhouse-jdbc/0.1.52, Apache 2.0 clickhouse-jdbc 0.1.52: https://mvnrepository.com/artifact/ru.yandex.clickhouse/clickhouse-jdbc/0.1.52, Apache 2.0
commons-beanutils 1.7.0 https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.7.0, Apache 2.0 commons-beanutils 1.9.4 https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.9.4, Apache 2.0
commons-cli 1.2: https://mvnrepository.com/artifact/commons-cli/commons-cli/1.2, Apache 2.0 commons-cli 1.2: https://mvnrepository.com/artifact/commons-cli/commons-cli/1.2, Apache 2.0
commons-codec 1.11: https://mvnrepository.com/artifact/commons-codec/commons-codec/1.11, Apache 2.0 commons-codec 1.11: https://mvnrepository.com/artifact/commons-codec/commons-codec/1.11, Apache 2.0
commons-collections 3.2.2: https://mvnrepository.com/artifact/commons-collections/commons-collections/3.2.2, Apache 2.0 commons-collections 3.2.2: https://mvnrepository.com/artifact/commons-collections/commons-collections/3.2.2, Apache 2.0

21
dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui vendored

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 xaboy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

4
dolphinscheduler-ui/package.json

@ -3,6 +3,8 @@
"version": "1.0.0", "version": "1.0.0",
"description": "A vue.js project", "description": "A vue.js project",
"author": "DolphinScheduler", "author": "DolphinScheduler",
"repository": "https://github.com/apache/incubator-dolphinscheduler",
"license": "Apache-2.0",
"scripts": { "scripts": {
"build": "npm run clean && cross-env NODE_ENV=production webpack --config ./build/webpack.config.prod.js", "build": "npm run clean && cross-env NODE_ENV=production webpack --config ./build/webpack.config.prod.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.config.dev.js", "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.config.dev.js",
@ -13,6 +15,7 @@
"build:release": "npm run clean && cross-env NODE_ENV=production PUBLIC_PATH=/dolphinscheduler/ui webpack --config ./build/webpack.config.release.js" "build:release": "npm run clean && cross-env NODE_ENV=production PUBLIC_PATH=/dolphinscheduler/ui webpack --config ./build/webpack.config.release.js"
}, },
"dependencies": { "dependencies": {
"@form-create/element-ui": "^1.0.18",
"@riophae/vue-treeselect": "^0.4.0", "@riophae/vue-treeselect": "^0.4.0",
"axios": "^0.16.2", "axios": "^0.16.2",
"bootstrap": "3.3.7", "bootstrap": "3.3.7",
@ -38,6 +41,7 @@
"vuex-router-sync": "^5.0.0" "vuex-router-sync": "^5.0.0"
}, },
"devDependencies": { "devDependencies": {
"acorn": "^7.4.1",
"autoprefixer": "^9.1.0", "autoprefixer": "^9.1.0",
"babel-core": "^6.25.0", "babel-core": "^6.25.0",
"babel-helper-vue-jsx-merge-props": "^2.0.2", "babel-helper-vue-jsx-merge-props": "^2.0.2",

2
dolphinscheduler-ui/src/js/conf/home/index.js

@ -38,6 +38,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js' import 'bootstrap/dist/js/bootstrap.min.js'
import 'canvg/dist/browser/canvg.min.js' import 'canvg/dist/browser/canvg.min.js'
import 'remixicon/fonts/remixicon.css' import 'remixicon/fonts/remixicon.css'
import formCreate from '@form-create/element-ui'
// Component internationalization // Component internationalization
const useOpt = i18n.globalScope.LOCALE === 'en_US' ? { locale: locale } : {} const useOpt = i18n.globalScope.LOCALE === 'en_US' ? { locale: locale } : {}
@ -46,6 +47,7 @@ i18n.globalScope.LOCALE === 'en_US' ? Vue.use(ElementUI, { locale }) : Vue.use(E
// Vue.use(ans) // Vue.use(ans)
Vue.use(useOpt) Vue.use(useOpt)
Vue.use(formCreate)
sync(store, router) sync(store, router)

55
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue

@ -55,18 +55,6 @@
</el-input> </el-input>
</div> </div>
</m-list-box> </m-list-box>
<m-list-box>
<div slot="text"><strong class='requiredIcon'>*</strong>{{$t('Recipient')}}</div>
<div slot="content">
<m-email ref="refEmail" v-model="receivers" :disabled="isDetails" :repeat-data="receiversCc"></m-email>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('Cc')}}</div>
<div slot="content">
<m-email ref="refCc" v-model="receiversCc" :disabled="isDetails" :repeat-data="receivers"></m-email>
</div>
</m-list-box>
</template> </template>
<m-list-box v-show="type === 'HIVE'"> <m-list-box v-show="type === 'HIVE'">
<div slot="text">{{$t('SQL Parameter')}}</div> <div slot="text">{{$t('SQL Parameter')}}</div>
@ -155,7 +143,6 @@
import mLocalParams from './_source/localParams' import mLocalParams from './_source/localParams'
import mStatementList from './_source/statementList' import mStatementList from './_source/statementList'
import disabledState from '@/module/mixin/disabledState' import disabledState from '@/module/mixin/disabledState'
import mEmail from '@/conf/home/pages/projects/pages/definition/pages/list/_source/email'
import codemirror from '@/conf/home/pages/resource/pages/file/pages/_source/codemirror' import codemirror from '@/conf/home/pages/resource/pages/file/pages/_source/codemirror'
let editor let editor
@ -188,10 +175,6 @@
preStatements: [], preStatements: [],
// Post statements // Post statements
postStatements: [], postStatements: [],
// recipients
receivers: [],
// copy to
receiversCc: [],
item: '', item: '',
scriptBoxDialog: false scriptBoxDialog: false
} }
@ -274,14 +257,6 @@
this.$message.warning(`${i18n.$t('Recipient required')}`) this.$message.warning(`${i18n.$t('Recipient required')}`)
return false return false
} }
// receivers Subcomponent verification
if (this.sqlType === 0 && !this.$refs.refEmail._manualEmail()) {
return false
}
// receiversCc Subcomponent verification
if (this.sqlType === 0 && !this.$refs.refCc._manualEmail()) {
return false
}
// udfs Subcomponent verification Verification only if the data type is HIVE // udfs Subcomponent verification Verification only if the data type is HIVE
if (this.type === 'HIVE') { if (this.type === 'HIVE') {
if (!this.$refs.refUdfs._verifUdfs()) { if (!this.$refs.refUdfs._verifUdfs()) {
@ -312,8 +287,6 @@
udfs: this.udfs, udfs: this.udfs,
sqlType: this.sqlType, sqlType: this.sqlType,
title: this.title, title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => { showType: (() => {
/** /**
* Special processing return order TABLE,ATTACHMENT * Special processing return order TABLE,ATTACHMENT
@ -366,19 +339,6 @@
return editor return editor
}, },
_getReceiver () {
let param = {}
let current = this.router.history.current
if (current.name === 'projects-definition-details') {
param.processDefinitionId = current.params.id
} else {
param.processInstanceId = current.params.id
}
this.store.dispatch('dag/getReceiver', param).then(res => {
this.receivers = res.receivers && res.receivers.split(',') || []
this.receiversCc = res.receiversCc && res.receiversCc.split(',') || []
})
},
_cacheParams () { _cacheParams () {
this.$emit('on-cache-params', { this.$emit('on-cache-params', {
type: this.type, type: this.type,
@ -387,8 +347,6 @@
udfs: this.udfs, udfs: this.udfs,
sqlType: this.sqlType, sqlType: this.sqlType,
title: this.title, title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => { showType: (() => {
let showType = this.showType let showType = this.showType
if (showType.length === 2 && showType[0] === 'ATTACHMENT') { if (showType.length === 2 && showType[0] === 'ATTACHMENT') {
@ -419,8 +377,6 @@
} }
if (val !== 0) { if (val !== 0) {
this.title = '' this.title = ''
this.receivers = []
this.receiversCc = []
} }
}, },
// Listening data source // Listening data source
@ -455,13 +411,6 @@
this.preStatements = o.params.preStatements || [] this.preStatements = o.params.preStatements || []
this.postStatements = o.params.postStatements || [] this.postStatements = o.params.postStatements || []
this.title = o.params.title || '' this.title = o.params.title || ''
this.receivers = o.params.receivers && o.params.receivers.split(',') || []
this.receiversCc = o.params.receiversCc && o.params.receiversCc.split(',') || []
}
// read tasks from cache
if (!_.some(this.store.state.dag.cacheTasks, { id: this.createNodeId }) &&
this.router.history.current.name !== 'definition-create') {
this._getReceiver()
} }
}, },
mounted () { mounted () {
@ -487,8 +436,6 @@
udfs: this.udfs, udfs: this.udfs,
sqlType: this.sqlType, sqlType: this.sqlType,
title: this.title, title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => { showType: (() => {
let showType = this.showType let showType = this.showType
if (showType.length === 2 && showType[0] === 'ATTACHMENT') { if (showType.length === 2 && showType[0] === 'ATTACHMENT') {
@ -504,6 +451,6 @@
} }
} }
}, },
components: { mListBox, mDatasource, mLocalParams, mUdfs, mSqlType, mStatementList, mEmail, mScriptBox } components: { mListBox, mDatasource, mLocalParams, mUdfs, mSqlType, mStatementList, mScriptBox }
} }
</script> </script>

1
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue

@ -1175,7 +1175,6 @@
} }
if (val !== 0) { if (val !== 0) {
this.title = '' this.title = ''
this.receivers = []
} }
}, },
// Listening data source // Listening data source

4
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/udp/udp.vue

@ -76,7 +76,7 @@
<div class="submit"> <div class="submit">
<template v-if="router.history.current.name === 'projects-definition-details'"> <template v-if="router.history.current.name === 'projects-definition-details'">
<div class="lint-pt"> <div class="lint-pt">
<el-checkbox v-model="releaseState" size="small" :false-label="0" :true-label="1">{{$t('Whether to go online the process definition')}}</el-checkbox> <el-checkbox v-model="releaseState" size="small" :false-label="'OFFLINE'" :true-label="'ONLINE'">{{$t('Whether to go online the process definition')}}</el-checkbox>
</div> </div>
</template> </template>
<template v-if="router.history.current.name === 'projects-instance-details'"> <template v-if="router.history.current.name === 'projects-instance-details'">
@ -112,7 +112,7 @@
// Global custom parameters // Global custom parameters
udpListCache: [], udpListCache: [],
// Whether to go online the process definition // Whether to go online the process definition
releaseState: 1, releaseState: 'ONLINE',
// Whether to update the process definition // Whether to update the process definition
syncDefine: true, syncDefine: true,
// Timeout alarm // Timeout alarm

2
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/_source/conditions/instance/processInstance.vue

@ -18,7 +18,7 @@
<m-conditions> <m-conditions>
<template slot="search-group"> <template slot="search-group">
<div class="list"> <div class="list">
<el-button type="primary" size="small" @click="_ckQuery" icon="el-icon-search"></el-button> <el-button size="mini" @click="_ckQuery" icon="el-icon-search"></el-button>
</div> </div>
<div class="list"> <div class="list">
<el-date-picker <el-date-picker

26
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -84,7 +84,6 @@
<el-button type="primary" size="mini" icon="el-icon-date" :disabled="scope.row.releaseState !== 'ONLINE'" @click="_timingManage(scope.row)" circle></el-button> <el-button type="primary" size="mini" icon="el-icon-date" :disabled="scope.row.releaseState !== 'ONLINE'" @click="_timingManage(scope.row)" circle></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip :content="$t('delete')" placement="top" :enterable="false"> <el-tooltip :content="$t('delete')" placement="top" :enterable="false">
<el-button type="danger" size="mini" icon="el-icon-delete" circle></el-button>
<el-popconfirm <el-popconfirm
:confirmButtonText="$t('Confirm')" :confirmButtonText="$t('Confirm')"
:cancelButtonText="$t('Cancel')" :cancelButtonText="$t('Cancel')"
@ -177,8 +176,6 @@
timingDialog: false, timingDialog: false,
timingData: { timingData: {
item: {}, item: {},
receiversD: [],
receiversCcD: [],
type: '' type: ''
}, },
relatedItemsDialog: false, relatedItemsDialog: false,
@ -191,7 +188,7 @@
pageSize: Number pageSize: Number
}, },
methods: { methods: {
...mapActions('dag', ['editProcessState', 'getStartCheck', 'getReceiver', 'deleteDefinition', 'batchDeleteDefinition', 'exportDefinition', 'getProcessDefinitionVersionsPage', 'copyProcess', 'switchProcessDefinitionVersion', 'deleteProcessDefinitionVersion', 'moveProcess']), ...mapActions('dag', ['editProcessState', 'getStartCheck', 'deleteDefinition', 'batchDeleteDefinition', 'exportDefinition', 'getProcessDefinitionVersionsPage', 'copyProcess', 'switchProcessDefinitionVersion', 'deleteProcessDefinitionVersion', 'moveProcess']),
...mapActions('security', ['getWorkerGroupsAll']), ...mapActions('security', ['getWorkerGroupsAll']),
selectable (row, index) { selectable (row, index) {
@ -226,30 +223,13 @@
closeStart () { closeStart () {
this.startDialog = false this.startDialog = false
}, },
/**
* get emial
*/
_getReceiver (id) {
return new Promise((resolve, reject) => {
this.getReceiver({ processDefinitionId: id }).then(res => {
resolve({
receivers: res.receivers && res.receivers.split(',') || [],
receiversCc: res.receiversCc && res.receiversCc.split(',') || []
})
})
})
},
/** /**
* timing * timing
*/ */
_timing (item) { _timing (item) {
this._getReceiver(item.id).then(res => {
this.timingData.item = item this.timingData.item = item
this.timingData.receiversD = res.receivers
this.timingData.receiversCcD = res.receiversCc
this.timingData.type = 'timing' this.timingData.type = 'timing'
this.timingDialog = true this.timingDialog = true
})
}, },
onUpdateTiming () { onUpdateTiming () {
this._onUpdate() this._onUpdate()
@ -295,7 +275,7 @@
_downline (item) { _downline (item) {
this._upProcessState({ this._upProcessState({
processId: item.id, processId: item.id,
releaseState: 0 releaseState: 'OFFLINE'
}) })
}, },
/** /**
@ -304,7 +284,7 @@
_poponline (item) { _poponline (item) {
this._upProcessState({ this._upProcessState({
processId: item.id, processId: item.id,
releaseState: 1 releaseState: 'ONLINE'
}) })
}, },
/** /**

31
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue

@ -99,22 +99,6 @@
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="clearfix list">
<div class="text">
{{$t('Recipient')}}
</div>
<div class="cont" style="width: 688px;">
<m-email v-model="receivers" :repeat-data="receiversCc"></m-email>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Cc')}}
</div>
<div class="cont" style="width: 688px;">
<m-email v-model="receiversCc" :repeat-data="receivers"></m-email>
</div>
</div>
<div class="clearfix list"> <div class="clearfix list">
<div class="text"> <div class="text">
{{$t('Complement Data')}} {{$t('Complement Data')}}
@ -181,7 +165,6 @@
<script> <script>
import _ from 'lodash' import _ from 'lodash'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import mEmail from './email.vue'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import { warningTypeList } from './util' import { warningTypeList } from './util'
import mPriority from '@/module/components/priority/priority' import mPriority from '@/module/components/priority/priority'
@ -206,8 +189,6 @@
spinnerLoading: false, spinnerLoading: false,
execType: false, execType: false,
taskDependType: 'TASK_POST', taskDependType: 'TASK_POST',
receivers: [],
receiversCc: [],
runMode: 'RUN_MODE_SERIAL', runMode: 'RUN_MODE_SERIAL',
processInstancePriority: 'MEDIUM', processInstancePriority: 'MEDIUM',
workerGroup: 'default', workerGroup: 'default',
@ -252,8 +233,6 @@
taskDependType: this.taskDependType, taskDependType: this.taskDependType,
runMode: this.runMode, runMode: this.runMode,
processInstancePriority: this.processInstancePriority, processInstancePriority: this.processInstancePriority,
receivers: this.receivers.join(',') || '',
receiversCc: this.receiversCc.join(',') || '',
workerGroup: this.workerGroup, workerGroup: this.workerGroup,
startParams: !_.isEmpty(startParams) ? JSON.stringify(startParams) : '' startParams: !_.isEmpty(startParams) ? JSON.stringify(startParams) : ''
} }
@ -283,12 +262,6 @@
}) })
}) })
}, },
_getReceiver () {
this.store.dispatch('dag/getReceiver', { processDefinitionId: this.startData.id }).then(res => {
this.receivers = res.receivers && res.receivers.split(',') || []
this.receiversCc = res.receiversCc && res.receiversCc.split(',') || []
})
},
_getGlobalParams () { _getGlobalParams () {
this.setIsDetails(true) this.setIsDetails(true)
this.store.dispatch('dag/getProcessDetails', this.startData.id).then(res => { this.store.dispatch('dag/getProcessDetails', this.startData.id).then(res => {
@ -311,8 +284,6 @@
created () { created () {
this.warningType = this.warningTypeList[0].id this.warningType = this.warningTypeList[0].id
this.workflowName = this.startData.name this.workflowName = this.startData.name
this._getReceiver()
this._getGlobalParams() this._getGlobalParams()
let stateWorkerGroupsList = this.store.state.security.workerGroupsListAll || [] let stateWorkerGroupsList = this.store.state.security.workerGroupsListAll || []
if (stateWorkerGroupsList.length) { if (stateWorkerGroupsList.length) {
@ -336,7 +307,7 @@
this.workflowName = this.startData.name this.workflowName = this.startData.name
}, },
computed: {}, computed: {},
components: { mEmail, mPriority, mWorkerGroups, mLocalParams } components: { mPriority, mWorkerGroups, mLocalParams }
} }
</script> </script>

26
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue

@ -136,22 +136,6 @@
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="clearfix list">
<div class="text">
{{$t('Recipient')}}
</div>
<div class="cont" style="width: 680px;">
<m-email v-model="receivers" :repeat-data="receiversCc"></m-email>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Cc')}}
</div>
<div class="cont" style="width: 680px;">
<m-email v-model="receiversCc" :repeat-data="receivers"></m-email>
</div>
</div>
<div class="submit"> <div class="submit">
<el-button type="text" size="small" @click="close()"> {{$t('Cancel')}} </el-button> <el-button type="text" size="small" @click="close()"> {{$t('Cancel')}} </el-button>
<el-button type="primary" size="small" round :loading="spinnerLoading" @click="ok()">{{spinnerLoading ? 'Loading...' : (timingData.item.crontab ? $t('Edit') : $t('Create'))}} </el-button> <el-button type="primary" size="small" round :loading="spinnerLoading" @click="ok()">{{spinnerLoading ? 'Loading...' : (timingData.item.crontab ? $t('Edit') : $t('Create'))}} </el-button>
@ -159,9 +143,7 @@
</div> </div>
</template> </template>
<script> <script>
import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import mEmail from './email.vue'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import { warningTypeList } from './util' import { warningTypeList } from './util'
import { vCrontab } from '@/module/components/crontab/index' import { vCrontab } from '@/module/components/crontab/index'
@ -184,8 +166,6 @@
scheduleTime: '', scheduleTime: '',
crontab: '0 0 * * * ? *', crontab: '0 0 * * * ? *',
cronPopover: false, cronPopover: false,
receivers: [],
receiversCc: [],
i18n: i18n.globalScope.LOCALE, i18n: i18n.globalScope.LOCALE,
processInstancePriority: 'MEDIUM', processInstancePriority: 'MEDIUM',
workerGroup: '', workerGroup: '',
@ -229,8 +209,6 @@
warningType: this.warningType, warningType: this.warningType,
processInstancePriority: this.processInstancePriority, processInstancePriority: this.processInstancePriority,
warningGroupId: this.warningGroupId === '' ? 0 : this.warningGroupId, warningGroupId: this.warningGroupId === '' ? 0 : this.warningGroupId,
receivers: this.receivers.join(',') || '',
receiversCc: this.receiversCc.join(',') || '',
workerGroup: this.workerGroup workerGroup: this.workerGroup
} }
let msg = '' let msg = ''
@ -337,8 +315,6 @@
this.crontab = '0 0 * * * ? *' this.crontab = '0 0 * * * ? *'
this.scheduleTime = times this.scheduleTime = times
} }
this.receivers = _.cloneDeep(this.timingData.receiversD)
this.receiversCc = _.cloneDeep(this.timingData.receiversCcD)
}, },
mounted () { mounted () {
let item = this.timingData.item let item = this.timingData.item
@ -363,7 +339,7 @@
}).catch(() => { this.warningGroupId = '' }) }).catch(() => { this.warningGroupId = '' })
} }
}, },
components: { vCrontab, mEmail, mPriority, mWorkerGroups } components: { vCrontab, mPriority, mWorkerGroups }
} }
</script> </script>

23
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue

@ -124,16 +124,14 @@
list: [], list: [],
timingDialog: false, timingDialog: false,
timingData: { timingData: {
item: {}, item: {}
receiversD: [],
receiversCcD: []
} }
} }
}, },
props: { props: {
}, },
methods: { methods: {
...mapActions('dag', ['getScheduleList', 'scheduleOffline', 'scheduleOnline', 'getReceiver', 'deleteTiming']), ...mapActions('dag', ['getScheduleList', 'scheduleOffline', 'scheduleOnline', 'deleteTiming']),
/** /**
* delete * delete
*/ */
@ -228,29 +226,12 @@
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
}) })
}, },
/**
* get email
*/
_getReceiver (id) {
return new Promise((resolve, reject) => {
this.getReceiver({ processDefinitionId: id }).then(res => {
resolve({
receivers: res.receivers && res.receivers.split(',') || [],
receiversCc: res.receiversCc && res.receiversCc.split(',') || []
})
})
})
},
/** /**
* timing * timing
*/ */
_editTiming (item) { _editTiming (item) {
this._getReceiver(item.processDefinitionId).then(res => {
this.timingData.item = item this.timingData.item = item
this.timingData.receiversD = res.receivers
this.timingData.receiversCcD = res.receiversCc
this.timingDialog = true this.timingDialog = true
})
}, },
onUpdateTiming () { onUpdateTiming () {
this.pageNo = 1 this.pageNo = 1

4
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -84,7 +84,6 @@
<span><el-button type="error" size="mini" :icon="scope.row.state === 'PAUSE' ? 'el-icon-video-play' : 'el-icon-video-pause'" :disabled="scope.row.state !== 'RUNNING_EXECUTION' && scope.row.state !== 'PAUSE'" @click="_suspend(scope.row,scope.$index)" circle></el-button></span> <span><el-button type="error" size="mini" :icon="scope.row.state === 'PAUSE' ? 'el-icon-video-play' : 'el-icon-video-pause'" :disabled="scope.row.state !== 'RUNNING_EXECUTION' && scope.row.state !== 'PAUSE'" @click="_suspend(scope.row,scope.$index)" circle></el-button></span>
</el-tooltip> </el-tooltip>
<el-tooltip :content="$t('delete')" placement="top" :enterable="false"> <el-tooltip :content="$t('delete')" placement="top" :enterable="false">
<el-button type="danger" size="mini" icon="el-icon-delete" circle></el-button>
<el-popconfirm <el-popconfirm
:confirmButtonText="$t('Confirm')" :confirmButtonText="$t('Confirm')"
:cancelButtonText="$t('Cancel')" :cancelButtonText="$t('Cancel')"
@ -92,7 +91,7 @@
iconColor="red" iconColor="red"
:title="$t('Delete?')" :title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)"> @onConfirm="_delete(scope.row,scope.row.id)">
<el-button type="danger" size="mini" icon="el-icon-delete" :disabled="scope.row.releaseState === 'ONLINE'" circle slot="reference"></el-button> <el-button type="danger" size="mini" icon="el-icon-delete" :disabled="scope.row.state !== 'SUCCESS' && scope.row.state !== 'FAILURE' && scope.row.state !== 'STOP' && scope.row.state !== 'PAUSE'" circle slot="reference"></el-button>
</el-popconfirm> </el-popconfirm>
</el-tooltip> </el-tooltip>
<el-tooltip :content="$t('Gantt')" placement="top" :enterable="false"> <el-tooltip :content="$t('Gantt')" placement="top" :enterable="false">
@ -453,7 +452,6 @@
_arrDelChange (v) { _arrDelChange (v) {
let arr = [] let arr = []
arr = _.map(v, 'id') arr = _.map(v, 'id')
console.log(arr)
this.strDelete = _.join(arr, ',') this.strDelete = _.join(arr, ',')
}, },
_batchDelete () { _batchDelete () {

16
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/list/_source/createProject.vue

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup ref="popup" :nameText="item ? $t('Edit') : $t('Create Project')" :ok-text="item ? $t('Edit') : $t('Submit')" <m-popover ref="popover" :nameText="item ? $t('Edit') : $t('Create Project')" :ok-text="item ? $t('Edit') : $t('Submit')"
@close="_close" @ok="_ok"> @close="_close" @ok="_ok">
<template slot="content"> <template slot="content">
<div class="projects-create-model"> <div class="projects-create-model">
@ -44,13 +44,13 @@
</m-list-box-f> </m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
@ -81,7 +81,7 @@
param.projectId = this.item.id param.projectId = this.item.id
} }
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch(`projects/${this.item ? 'updateProjects' : 'createProjects'}`, param).then(res => { this.store.dispatch(`projects/${this.item ? 'updateProjects' : 'createProjects'}`, param).then(res => {
this.$emit('_onUpdate') this.$emit('_onUpdate')
@ -90,12 +90,10 @@
type: 'success', type: 'success',
offset: 70 offset: 70
}) })
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
}).catch(e => { }).catch(e => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
}) })
}, },
_close () { _close () {
@ -118,6 +116,6 @@
}, },
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

2
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/list/index.vue

@ -21,6 +21,8 @@
<template slot="button-group"> <template slot="button-group">
<el-button size="mini" @click="_create('')">{{ $t('Create Project') }}</el-button> <el-button size="mini" @click="_create('')">{{ $t('Create Project') }}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit') : $t('Create Project')"
v-if="createProjectDialog"
:visible.sync="createProjectDialog" :visible.sync="createProjectDialog"
width="auto"> width="auto">
<m-create-project :item="item" @_onUpdate="_onUpdate" @close="_close"></m-create-project> <m-create-project :item="item" @_onUpdate="_onUpdate" @close="_close"></m-create-project>

21
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/_source/createQueue.vue

@ -15,10 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup <m-popover
ref="popup" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit queue') : $t('Create queue')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close">
<template slot="content"> <template slot="content">
@ -50,13 +49,13 @@
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
@ -89,18 +88,16 @@
let $then = (res) => { let $then = (res) => {
this.$emit('onUpdate') this.$emit('onUpdate')
this.$message.success(res.msg) this.$message.success(res.msg)
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
} }
let $catch = (e) => { let $catch = (e) => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
} }
if (this.item) { if (this.item) {
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch('security/updateQueueQ', param).then(res => { this.store.dispatch('security/updateQueueQ', param).then(res => {
$then(res) $then(res)
}).catch(e => { }).catch(e => {
@ -108,7 +105,7 @@
}) })
} else { } else {
this._verifyName(param).then(() => { this._verifyName(param).then(() => {
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch('security/createQueueQ', param).then(res => { this.store.dispatch('security/createQueueQ', param).then(res => {
$then(res) $then(res)
}).catch(e => { }).catch(e => {
@ -154,6 +151,6 @@
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

2
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue

@ -21,6 +21,8 @@
<template slot="button-group" v-if="isADMIN"> <template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create queue')}}</el-button> <el-button size="mini" @click="_create('')">{{$t('Create queue')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit queue') : $t('Create queue')"
:v-if="createQueueDialog"
:visible.sync="createQueueDialog" :visible.sync="createQueueDialog"
width="auto"> width="auto">
<m-create-queue :item="item" @onUpdate="onUpdate" @close="close"></m-create-queue> <m-create-queue :item="item" @onUpdate="onUpdate" @close="close"></m-create-queue>

19
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/_source/createTenement.vue

@ -15,10 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup <m-popover
ref="popup" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit Tenant') : $t('Create Tenant')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close">
<template slot="content"> <template slot="content">
@ -62,13 +61,13 @@
</m-list-box-f> </m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
name: 'create-tenement', name: 'create-tenement',
@ -141,16 +140,14 @@
if (this.item) { if (this.item) {
param.id = this.item.id param.id = this.item.id
} }
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch(`security/${this.item ? 'updateQueue' : 'createQueue'}`, param).then(res => { this.store.dispatch(`security/${this.item ? 'updateQueue' : 'createQueue'}`, param).then(res => {
this.$emit('onUpdate') this.$emit('onUpdate')
this.$message.success(res.msg) this.$message.success(res.msg)
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
}).catch(e => { }).catch(e => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
}) })
}, },
close () { close () {
@ -172,6 +169,6 @@
}, },
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

2
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue

@ -21,6 +21,8 @@
<template slot="button-group" v-if="isADMIN"> <template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create Tenant')}}</el-button> <el-button size="mini" @click="_create('')">{{$t('Create Tenant')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit Tenant') : $t('Create Tenant')"
v-if="createTenementDialog"
:visible.sync="createTenementDialog" :visible.sync="createTenementDialog"
width="auto"> width="auto">
<m-create-tenement :item="item" @onUpdate="onUpdate" @close="close"></m-create-tenement> <m-create-tenement :item="item" @onUpdate="onUpdate" @close="close"></m-create-tenement>

23
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue

@ -15,10 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup <m-popover
ref="popup" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit User') : $t('Create User')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close">
<template slot="content"> <template slot="content">
@ -30,6 +29,7 @@
type="input" type="input"
v-model="userName" v-model="userName"
maxlength="60" maxlength="60"
size="small"
:placeholder="$t('Please enter user name')"> :placeholder="$t('Please enter user name')">
</el-input> </el-input>
</template> </template>
@ -40,6 +40,7 @@
<el-input <el-input
type="password" type="password"
v-model="userPassword" v-model="userPassword"
size="small"
:placeholder="$t('Please enter your password')"> :placeholder="$t('Please enter your password')">
</el-input> </el-input>
</template> </template>
@ -80,6 +81,7 @@
<el-input <el-input
type="input" type="input"
v-model="email" v-model="email"
size="small"
:placeholder="$t('Please enter email')"> :placeholder="$t('Please enter email')">
</el-input> </el-input>
</template> </template>
@ -90,6 +92,7 @@
<el-input <el-input
type="input" type="input"
v-model="phone" v-model="phone"
size="small"
:placeholder="$t('Please enter phone number')"> :placeholder="$t('Please enter phone number')">
</el-input> </el-input>
</template> </template>
@ -105,14 +108,14 @@
</m-list-box-f> </m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import router from '@/conf/home/router' import router from '@/conf/home/router'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
@ -243,7 +246,7 @@
}) })
}, },
_submit () { _submit () {
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
let queueCode = '' let queueCode = ''
// get queue code // get queue code
@ -265,14 +268,12 @@
} }
this.store.dispatch(`security/${this.item ? 'updateUser' : 'createUser'}`, param).then(res => { this.store.dispatch(`security/${this.item ? 'updateUser' : 'createUser'}`, param).then(res => {
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
this.$emit('onUpdate', param) this.$emit('onUpdate', param)
this.$message.success(res.msg) this.$message.success(res.msg)
}).catch(e => { }).catch(e => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
}) })
}, },
close () { close () {
@ -315,6 +316,6 @@
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

4
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue

@ -81,24 +81,28 @@
</el-table> </el-table>
</div> </div>
<el-dialog <el-dialog
v-if="authProjectDialog"
:visible.sync="authProjectDialog" :visible.sync="authProjectDialog"
width="auto"> width="auto">
<m-transfer :transferData="transferData" @onUpdateAuthProject="onUpdateAuthProject" @closeAuthProject="closeAuthProject"></m-transfer> <m-transfer :transferData="transferData" @onUpdateAuthProject="onUpdateAuthProject" @closeAuthProject="closeAuthProject"></m-transfer>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
v-if="authDataSourceDialog"
:visible.sync="authDataSourceDialog" :visible.sync="authDataSourceDialog"
width="auto"> width="auto">
<m-transfer :transferData="transferData" @onUpdateAuthDataSource="onUpdateAuthDataSource" @closeAuthDataSource="closeAuthDataSource"></m-transfer> <m-transfer :transferData="transferData" @onUpdateAuthDataSource="onUpdateAuthDataSource" @closeAuthDataSource="closeAuthDataSource"></m-transfer>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
v-if="authUdfFuncDialog"
:visible.sync="authUdfFuncDialog" :visible.sync="authUdfFuncDialog"
width="auto"> width="auto">
<m-transfer :transferData="transferData" @onUpdateAuthUdfFunc="onUpdateAuthUdfFunc" @closeAuthUdfFunc="closeAuthUdfFunc"></m-transfer> <m-transfer :transferData="transferData" @onUpdateAuthUdfFunc="onUpdateAuthUdfFunc" @closeAuthUdfFunc="closeAuthUdfFunc"></m-transfer>
</el-dialog> </el-dialog>
<el-dialog <el-dialog
v-if="resourceDialog"
:visible.sync="resourceDialog" :visible.sync="resourceDialog"
width="auto"> width="auto">
<m-resource :resourceData="resourceData" @onUpdateAuthResource="onUpdateAuthResource" @closeAuthResource="closeAuthResource"></m-resource> <m-resource :resourceData="resourceData" @onUpdateAuthResource="onUpdateAuthResource" @closeAuthResource="closeAuthResource"></m-resource>

2
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue

@ -21,6 +21,8 @@
<template slot="button-group" v-if="userList.length"> <template slot="button-group" v-if="userList.length">
<el-button size="mini" @click="_create('')">{{$t('Create User')}}</el-button> <el-button size="mini" @click="_create('')">{{$t('Create User')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit User') : $t('Create User')"
v-if="createUserDialog"
:visible.sync="createUserDialog" :visible.sync="createUserDialog"
width="auto"> width="auto">
<m-create-user :item="item" @onUpdate="onUpdate" @close="close"></m-create-user> <m-create-user :item="item" @onUpdate="onUpdate" @close="close"></m-create-user>

47
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue

@ -15,10 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup <m-popover
ref="popup" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit alarm group') : $t('Create alarm group')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close">
<template slot="content"> <template slot="content">
@ -36,14 +35,14 @@
</template> </template>
</m-list-box-f> </m-list-box-f>
<m-list-box-f> <m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Group Type')}}</template> <template slot="name"><strong>*</strong>{{$t('Alarm plugin instance')}}</template>
<template slot="content"> <template slot="content">
<el-select v-model="groupType" size="small"> <el-select v-model="alertInstanceIds" size="small" style="width: 100%" multiple>
<el-option <el-option
v-for="city in options" v-for="items in allAlertPluginInstance"
:key="city.id" :key="items.id"
:value="city.id" :value="items.id"
:label="city.code"> :label="items.instanceName">
</el-option> </el-option>
</el-select> </el-select>
</template> </template>
@ -61,12 +60,13 @@
</m-list-box-f> </m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash'
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
@ -75,13 +75,13 @@
return { return {
store, store,
groupName: '', groupName: '',
groupType: 'EMAIL', alertInstanceIds: [],
description: '', description: ''
options: [{ code: `${i18n.$t('Email')}`, id: 'EMAIL' }, { code: `${i18n.$t('SMS')}`, id: 'SMS' }]
} }
}, },
props: { props: {
item: Object item: Object,
allAlertPluginInstance: Array
}, },
methods: { methods: {
_ok () { _ok () {
@ -114,22 +114,20 @@
_submit () { _submit () {
let param = { let param = {
groupName: this.groupName, groupName: this.groupName,
groupType: this.groupType, alertInstanceIds: this.alertInstanceIds.join(','),
description: this.description description: this.description
} }
if (this.item) { if (this.item) {
param.id = this.item.id param.id = this.item.id
} }
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch(`security/${this.item ? 'updateAlertgrou' : 'createAlertgrou'}`, param).then(res => { this.store.dispatch(`security/${this.item ? 'updateAlertgrou' : 'createAlertgrou'}`, param).then(res => {
this.$emit('onUpdate') this.$emit('onUpdate')
this.$message.success(res.msg) this.$message.success(res.msg)
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
}).catch(e => { }).catch(e => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
}) })
}, },
close () { close () {
@ -140,12 +138,15 @@
created () { created () {
if (this.item) { if (this.item) {
this.groupName = this.item.groupName this.groupName = this.item.groupName
this.groupType = this.item.groupType let dataStrArr = this.item.alertInstanceIds.split(',')
this.alertInstanceIds = _.map(dataStrArr, v => {
return +v
})
this.description = this.item.description this.description = this.item.description
} }
}, },
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

55
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue

@ -20,11 +20,6 @@
<el-table :data="list" size="mini" style="width: 100%"> <el-table :data="list" size="mini" style="width: 100%">
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column> <el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="groupName" :label="$t('Group Name')"></el-table-column> <el-table-column prop="groupName" :label="$t('Group Name')"></el-table-column>
<el-table-column :label="$t('Group Type')" width="100">
<template slot-scope="scope">
{{scope.row.groupType === 'EMAIL' ? `${$t('Email')}` : `${$t('SMS')}`}}
</template>
</el-table-column>
<el-table-column prop="description" :label="$t('Remarks')" width="200"></el-table-column> <el-table-column prop="description" :label="$t('Remarks')" width="200"></el-table-column>
<el-table-column :label="$t('Create Time')" width="140"> <el-table-column :label="$t('Create Time')" width="140">
<template slot-scope="scope"> <template slot-scope="scope">
@ -38,9 +33,6 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Operation')" width="130"> <el-table-column :label="$t('Operation')" width="130">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip :content="$t('Managing Users')" placement="top">
<el-button type="primary" size="mini" icon="el-icon-user" @click="_mangeUser(scope.row, scope.$index)" circle></el-button>
</el-tooltip>
<el-tooltip :content="$t('Edit')" placement="top"> <el-tooltip :content="$t('Edit')" placement="top">
<span><el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button></span> <span><el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button></span>
</el-tooltip> </el-tooltip>
@ -53,25 +45,17 @@
:title="$t('Delete?')" :title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)" @onConfirm="_delete(scope.row,scope.row.id)"
> >
<el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference" :disabled="scope.row.id==1?true: false"></el-button> <el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button>
</el-popconfirm> </el-popconfirm>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<el-dialog
:visible.sync="transferDialog"
width="auto">
<m-transfer :transferData="transferData" @onUpdate="onUpdate" @close="close"></m-transfer>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import { mapActions } from 'vuex' import { mapActions } from 'vuex'
import mTransfer from '@/module/components/transfer/transfer'
export default { export default {
name: 'user-list', name: 'user-list',
@ -79,14 +63,7 @@
return { return {
list: [], list: [],
transferDialog: false, transferDialog: false,
item: {}, item: {}
transferData: {
sourceListPrs: [],
targetListPrs: [],
type: {
name: `${i18n.$t('Managing Users')}`
}
}
} }
}, },
props: { props: {
@ -95,7 +72,7 @@
pageSize: Number pageSize: Number
}, },
methods: { methods: {
...mapActions('security', ['deleteAlertgrou', 'getAuthList', 'grantAuthorization']), ...mapActions('security', ['deleteAlertgrou', 'grantAuthorization']),
_delete (item, i) { _delete (item, i) {
this.deleteAlertgrou({ this.deleteAlertgrou({
id: item.id id: item.id
@ -109,30 +86,6 @@
_edit (item) { _edit (item) {
this.$emit('on-edit', item) this.$emit('on-edit', item)
}, },
_mangeUser (item, i) {
this.getAuthList({
id: item.id,
type: 'user',
category: 'users'
}).then(data => {
let sourceListPrs = _.map(data[0], v => {
return {
id: v.id,
name: v.userName
}
})
let targetListPrs = _.map(data[1], v => {
return {
id: v.id,
name: v.userName
}
})
this.item = item
this.transferData.sourceListPrs = sourceListPrs
this.transferData.targetListPrs = targetListPrs
this.transferDialog = true
})
},
onUpdate (userIds) { onUpdate (userIds) {
this._grantAuthorization('alert-group/grant-user', { this._grantAuthorization('alert-group/grant-user', {
userIds: userIds, userIds: userIds,
@ -168,6 +121,6 @@
}, },
mounted () { mounted () {
}, },
components: { mTransfer } components: {}
} }
</script> </script>

16
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue

@ -21,9 +21,11 @@
<template slot="button-group" v-if="isADMIN"> <template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create alarm group')}}</el-button> <el-button size="mini" @click="_create('')">{{$t('Create alarm group')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit alarm group') : $t('Create alarm group')"
v-if="createWarningDialog"
:visible.sync="createWarningDialog" :visible.sync="createWarningDialog"
width="auto"> width="auto">
<m-create-warning :item="item" @onUpdate="onUpdate" @close="close"></m-create-warning> <m-create-warning :item="item" :allAlertPluginInstance="allAlertPluginInstance" @onUpdate="onUpdate" @close="close"></m-create-warning>
</el-dialog> </el-dialog>
</template> </template>
</m-conditions> </m-conditions>
@ -83,13 +85,14 @@
isLeft: true, isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER', isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
createWarningDialog: false, createWarningDialog: false,
item: {} item: {},
allAlertPluginInstance: []
} }
}, },
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
props: {}, props: {},
methods: { methods: {
...mapActions('security', ['getAlertgroupP']), ...mapActions('security', ['queryAlertGroupListPaging', 'queryAllAlertPluginInstance']),
/** /**
* Inquire * Inquire
*/ */
@ -110,6 +113,11 @@
this._create(item) this._create(item)
}, },
_create (item) { _create (item) {
this.queryAllAlertPluginInstance().then(res => {
this.allAlertPluginInstance = res
}).catch(e => {
this.$message.error(e.msg)
})
this.item = item this.item = item
this.createWarningDialog = true this.createWarningDialog = true
}, },
@ -130,7 +138,7 @@
this.isLeft = true this.isLeft = true
} }
this.isLoading = !flag this.isLoading = !flag
this.getAlertgroupP(this.searchParams).then(res => { this.queryAlertGroupListPaging(this.searchParams).then(res => {
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) { if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
this.searchParams.pageNo = this.searchParams.pageNo - 1 this.searchParams.pageNo = this.searchParams.pageNo - 1
} else { } else {

197
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue

@ -0,0 +1,197 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<m-popover
ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')"
@ok="_ok"
@close="close">
<template slot="content">
<div class="create-warning-model">
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Alarm instance name')}}</template>
<template slot="content">
<el-input
type="input"
v-model="instanceName"
maxlength="60"
size="small"
:placeholder="$t('Please enter group name')">
</el-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Select plugin')}}</template>
<template slot="content">
<el-select v-model="pluginDefineId" size="small" style="width: 100%" @change="changePlugin" disabled="true" v-if="item.id">
<el-option
v-for="items in pulginInstance"
:key="items.id"
:value="items.id"
:label="items.pluginName">
</el-option>
</el-select>
<el-select v-model="pluginDefineId" size="small" style="width: 100%" @change="changePlugin" v-else>
<el-option
v-for="items in pulginInstance"
:key="items.id"
:value="items.id"
:label="items.pluginName">
</el-option>
</el-select>
</template>
</m-list-box-f>
<div class="alertForm">
<template>
<form-create v-model="$f" :rule="rule" :option="{submitBtn:false}" size="mini"></form-create>
</template>
</div>
</div>
</template>
</m-popover>
</template>
<script>
import i18n from '@/module/i18n'
import store from '@/conf/home/store'
import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default {
name: 'create-warning',
data () {
return {
store,
instanceName: '',
pluginDefineId: null,
$f: {},
rule: []
}
},
props: {
item: Object,
pulginInstance: Array
},
methods: {
_ok () {
if (this._verification()) {
// The name is not verified
if (this.item && this.item.instanceName === this.instanceName) {
this._submit()
return
}
// Verify username
this.store.dispatch('security/verifyName', {
type: 'alarmInstance',
instanceName: this.instanceName
}).then(res => {
this._submit()
}).catch(e => {
this.$message.error(e.msg || '')
})
}
},
_verification () {
// group name
if (!this.instanceName.replace(/\s*/g, '')) {
this.$message.warning(`${i18n.$t('Please enter group name')}`)
return false
}
return true
},
// Select plugin
changePlugin () {
this.store.dispatch('security/getUiPluginById', {
pluginId: this.pluginDefineId
}).then(res => {
this.rule = JSON.parse(res.pluginParams)
this.rule.forEach(item => {
if (item.title.indexOf('$t') !== -1) {
item.title = $t(item.field)
}
})
}).catch(e => {
this.$message.error(e.msg || '')
})
},
_submit () {
this.$f.rule.forEach(item => {
item.title = item.name
})
let param = {
instanceName: this.instanceName,
pluginDefineId: this.pluginDefineId,
pluginInstanceParams: JSON.stringify(this.$f.rule)
}
if (this.item) {
param.alertPluginInstanceId = this.item.id
param.pluginDefineId = null
}
this.$refs.popover.spinnerLoading = true
this.store.dispatch(`security/${this.item ? 'updateAlertPluginInstance' : 'createAlertPluginInstance'}`, param).then(res => {
this.$refs.popover.spinnerLoading = false
this.$emit('onUpdate')
this.$message.success(res.msg)
}).catch(e => {
this.$message.error(e.msg || '')
this.$refs.popover.spinnerLoading = false
})
},
close () {
this.$emit('close')
}
},
watch: {},
created () {
let pluginInstanceParams = []
if (this.item) {
this.instanceName = this.item.instanceName
this.pluginDefineId = this.item.pluginDefineId
JSON.parse(this.item.pluginInstanceParams).forEach(item => {
if (item.title.indexOf('$t') !== -1) {
item.title = $t(item.field)
}
pluginInstanceParams.push(item)
})
this.rule = pluginInstanceParams
}
},
mounted () {
},
components: { mPopover, mListBoxF }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.alertForm {
label {
span {
font-weight: 10!important;
}
}
.el-row {
width: 520px;
}
.el-form-item__label {
width: 144px!important;
color: #606266!important;
}
.el-form-item__content {
margin-left: 144px!important;
width: calc(100% - 162px);
}
}
</style>

107
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<div class="list-model">
<div class="table-box">
<el-table :data="list" size="mini" style="width: 100%">
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="instanceName" :label="$t('Alarm instance name')"></el-table-column>
<el-table-column :label="$t('Create Time')">
<template slot-scope="scope">
<span>{{scope.row.createTime | formatDate}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('Update Time')">
<template slot-scope="scope">
<span>{{scope.row.updateTime | formatDate}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('Operation')" width="130">
<template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top">
<span><el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button></span>
</el-tooltip>
<el-tooltip :content="$t('delete')" placement="top">
<el-popconfirm
:confirmButtonText="$t('Confirm')"
:cancelButtonText="$t('Cancel')"
icon="el-icon-info"
iconColor="red"
:title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)"
>
<el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button>
</el-popconfirm>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'user-list',
data () {
return {
list: [],
transferDialog: false,
item: {}
}
},
props: {
alertgroupList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('security', ['deletAelertPluginInstance']),
_delete (item, i) {
this.deletAelertPluginInstance({
id: item.id
}).then(res => {
this.$emit('on-update')
this.$message.success(res.msg)
}).catch(e => {
this.$message.error(e.msg || '')
})
},
_edit (item) {
this.$emit('on-edit', item)
},
close () {
this.transferDialog = false
}
},
watch: {
alertgroupList (a) {
this.list = []
setTimeout(() => {
this.list = a
})
}
},
created () {
this.list = this.alertgroupList
},
mounted () {
},
components: {}
}
</script>

171
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue

@ -0,0 +1,171 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<m-list-construction :title="$t('Warning instance manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create Alarm Instance')}}</el-button>
<el-dialog
:title="item ? $t('Edit Alarm Instance') : $t('Create Alarm Instance')"
v-if="createWarningDialog"
:visible.sync="createWarningDialog"
width="auto">
<m-create-warning-instance :item="item" :pulginInstance="pulginInstance" @onUpdate="onUpdate" @close="close"></m-create-warning-instance>
</el-dialog>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="alertgroupList!==null || total>0 ">
<m-list @on-edit="_onEdit"
@on-update="_onUpdate"
:alertgroup-list="alertgroupList"
:page-no="searchParams.pageNo"
:page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<el-pagination
background
@current-change="_page"
@size-change="_pageSize"
:page-size="searchParams.pageSize"
:current-page.sync="searchParams.pageNo"
:page-sizes="[10, 30, 50]"
layout="sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</template>
<template v-if="alertgroupList===null && total<=0">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
import { mapActions } from 'vuex'
import mList from './_source/list'
import store from '@/conf/home/store'
import mSpin from '@/module/components/spin/spin'
import mCreateWarningInstance from './_source/createWarningInstance'
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'warning-instance-index',
data () {
return {
total: null,
isLoading: false,
alertgroupList: [],
searchParams: {
pageSize: 10,
pageNo: 1,
searchVal: ''
},
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
createWarningDialog: false,
item: {},
pulginInstance: []
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['queryAlertPluginInstanceListPaging', 'getPlugins']),
/**
* Inquire
*/
_onConditions (o) {
this.searchParams = _.assign(this.searchParams, o)
this.searchParams.pageNo = 1
},
_page (val) {
this.searchParams.pageNo = val
},
_pageSize (val) {
this.searchParams.pageSize = val
},
_onUpdate () {
this._debounceGET()
},
_onEdit (item) {
this._create(item)
},
_create (item) {
this.getPlugins({ pluginType: 'ALERT' }).then(res => {
this.pulginInstance = res
}).catch(e => {
this.$message.error(e.msg)
})
this.item = item
this.createWarningDialog = true
},
onUpdate () {
this._debounceGET('false')
this.createWarningDialog = false
},
close () {
this.createWarningDialog = false
},
_getList (flag) {
if (sessionStorage.getItem('isLeft') === 0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag
this.queryAlertPluginInstanceListPaging(this.searchParams).then(res => {
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
this.searchParams.pageNo = this.searchParams.pageNo - 1
} else {
this.alertgroupList = []
this.alertgroupList = res.totalList
this.total = res.total
this.isLoading = false
}
}).catch(e => {
this.isLoading = false
})
}
},
watch: {
// router
'$route' (a) {
// url no params get instance list
this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo
}
},
created () {
},
mounted () {
},
beforeDestroy () {
sessionStorage.setItem('isLeft', 1)
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWarningInstance }
}
</script>

4
dolphinscheduler-ui/src/js/conf/home/pages/user/pages/account/_source/info.vue

@ -69,6 +69,8 @@
<template slot="content"> <template slot="content">
<el-button type="primary" size="small" round @click="_edit()" >{{$t('Edit')}}</el-button> <el-button type="primary" size="small" round @click="_edit()" >{{$t('Edit')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit User') : $t('Create User')"
v-if="createUserDialog"
:visible.sync="createUserDialog" :visible.sync="createUserDialog"
width="auto"> width="auto">
<m-create-user :item="item" @onUpdate="onUpdate" @close="close"></m-create-user> <m-create-user :item="item" @onUpdate="onUpdate" @close="close"></m-create-user>
@ -131,12 +133,10 @@
padding-top: 30px; padding-top: 30px;
.list-box-f { .list-box-f {
.text { .text {
width: 200px;
font-size: 14px; font-size: 14px;
color: #888; color: #888;
} }
.cont { .cont {
width: calc(100% - 210px);
margin-left: 10px; margin-left: 10px;
.sp1 { .sp1 {
font-size: 14px; font-size: 14px;

19
dolphinscheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue

@ -15,10 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
<template> <template>
<m-popup <m-popover
ref="popup" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit token') : $t('Create token')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close">
<template slot="content"> <template slot="content">
@ -65,7 +64,7 @@
</m-list-box-f> </m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popover>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
@ -73,7 +72,7 @@
import i18n from '@/module/i18n' import i18n from '@/module/i18n'
import store from '@/conf/home/store' import store from '@/conf/home/store'
import Permissions from '@/module/permissions' import Permissions from '@/module/permissions'
import mPopup from '@/module/components/popup/popup' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default { export default {
@ -120,16 +119,14 @@
if (this.item) { if (this.item) {
param.id = this.item.id param.id = this.item.id
} }
this.$refs.popup.spinnerLoading = true this.$refs.popover.spinnerLoading = true
this.store.dispatch(`user/${this.item ? 'updateToken' : 'createToken'}`, param).then(res => { this.store.dispatch(`user/${this.item ? 'updateToken' : 'createToken'}`, param).then(res => {
this.$emit('onUpdate') this.$emit('onUpdate')
this.$message.success(res.msg) this.$message.success(res.msg)
setTimeout(() => { this.$refs.popover.spinnerLoading = false
this.$refs.popup.spinnerLoading = false
}, 800)
}).catch(e => { }).catch(e => {
this.$message.error(e.msg || '') this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false this.$refs.popover.spinnerLoading = false
}) })
}, },
_generateToken () { _generateToken () {
@ -177,7 +174,7 @@
}, },
mounted () { mounted () {
}, },
components: { mPopup, mListBoxF } components: { mPopover, mListBoxF }
} }
</script> </script>

2
dolphinscheduler-ui/src/js/conf/home/pages/user/pages/token/index.vue

@ -21,6 +21,8 @@
<template slot="button-group"> <template slot="button-group">
<el-button size="mini" @click="_create('')">{{$t('Create token')}}</el-button> <el-button size="mini" @click="_create('')">{{$t('Create token')}}</el-button>
<el-dialog <el-dialog
:title="item ? $t('Edit token') : $t('Create token')"
v-if="createTokenDialog"
:visible.sync="createTokenDialog" :visible.sync="createTokenDialog"
width="auto"> width="auto">
<m-create-token :item="item" @onUpdate="onUpdate" @close="close"></m-create-token> <m-create-token :item="item" @onUpdate="onUpdate" @close="close"></m-create-token>

16
dolphinscheduler-ui/src/js/conf/home/router/index.js

@ -387,7 +387,8 @@ const router = new Router({
name: 'users-manage', name: 'users-manage',
component: resolve => require(['../pages/security/pages/users/index'], resolve), component: resolve => require(['../pages/security/pages/users/index'], resolve),
meta: { meta: {
title: `${i18n.$t('User Manage')}` title: `${i18n.$t('User Manage')}`,
refresh_in_switched_tab: true
} }
}, },
{ {
@ -398,6 +399,14 @@ const router = new Router({
title: `${i18n.$t('Warning group manage')}` title: `${i18n.$t('Warning group manage')}`
} }
}, },
{
path: '/security/warning-instance',
name: 'warning-instance-manage',
component: resolve => require(['../pages/security/pages/warningInstance/index'], resolve),
meta: {
title: `${i18n.$t('Warning instance manage')}`
}
},
{ {
path: '/security/queue', path: '/security/queue',
name: 'queue-manage', name: 'queue-manage',
@ -549,6 +558,11 @@ const router = new Router({
] ]
}) })
const VueRouterPush = Router.prototype.push
Router.prototype.push = function push (to) {
return VueRouterPush.call(this, to).catch(err => err)
}
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
const $body = $('body') const $body = $('body')
$body.find('.tooltip.fade.top.in').remove() $body.find('.tooltip.fade.top.in').remove()

2
dolphinscheduler-ui/src/js/conf/home/store/dag/state.js

@ -46,7 +46,7 @@ export default {
// Current project // Current project
projectName: projectName || '', projectName: projectName || '',
// Whether to go online the process definition // Whether to go online the process definition
releaseState: 1, releaseState: 'ONLINE',
// Whether to update the process definition // Whether to update the process definition
syncDefine: true, syncDefine: true,
// tasks processList // tasks processList

94
dolphinscheduler-ui/src/js/conf/home/store/security/actions.js

@ -43,6 +43,12 @@ export default {
groupName: payload.groupName groupName: payload.groupName
}, },
api: 'alert-group/verify-group-name' api: 'alert-group/verify-group-name'
},
alarmInstance: {
param: {
alertInstanceName: payload.instanceName
},
api: 'alert-plugin-instance/verify-alert-instance-name'
} }
} }
@ -340,9 +346,9 @@ export default {
}) })
}, },
/** /**
* Paging query alarm group list * queryAlertGroupListPaging
*/ */
getAlertgroupP ({ state }, payload) { queryAlertGroupListPaging ({ state }, payload) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
io.get('alert-group/list-paging', payload, res => { io.get('alert-group/list-paging', payload, res => {
resolve(res.data) resolve(res.data)
@ -351,6 +357,54 @@ export default {
}) })
}) })
}, },
/**
* queryAlertPluginInstanceListPaging
*/
queryAlertPluginInstanceListPaging ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/list-paging', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryUiPlugins
*/
getPlugins ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('ui-plugins/queryUiPluginsByType', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryUiPluginById
*/
getUiPluginById ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('ui-plugins/queryUiPluginDetailById', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryAll alert-plugin-instance
*/
queryAllAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('alert-plugin-instance/queryAll', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/** /**
* Alarm group list * Alarm group list
*/ */
@ -375,6 +429,30 @@ export default {
}) })
}) })
}, },
/**
* create alert plugin instance operation
*/
createAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('alert-plugin-instance/create', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* update alert plugin instance operation
*/
updateAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/update', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/** /**
* update an alarm group. * update an alarm group.
*/ */
@ -399,6 +477,18 @@ export default {
}) })
}) })
}, },
/**
* delete alert plugin instance operation
*/
deletAelertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/delete', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/** /**
* Master list * Master list
*/ */

97
dolphinscheduler-ui/src/js/module/components/popup/popover.vue

@ -0,0 +1,97 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<div class="popup-model">
<div class="content-p">
<slot name="content"></slot>
</div>
<div class="bottom-p">
<el-button type="text" size="mini" round @click="close()" :disabled="disabled"> {{$t('Cancel')}} </el-button>
<el-button type="primary" size="mini" round :loading="spinnerLoading" @click="ok()" :disabled="disabled || apDisabled">{{spinnerLoading ? 'Loading...' : okText}} </el-button>
</div>
</div>
</template>
<script>
import i18n from '@/module/i18n'
export default {
name: 'popup',
data () {
return {
spinnerLoading: false,
apDisabled: false
}
},
props: {
okText: {
type: String,
default: `${i18n.$t('Confirm')}`
},
disabled: {
type: Boolean,
default: false
},
asynLoading: {
type: Boolean,
default: false
}
},
methods: {
close () {
this.$emit('close')
},
ok () {
if (this.asynLoading) {
this.spinnerLoading = true
this.$emit('ok', () => {
this.spinnerLoading = false
})
} else {
this.$emit('ok')
}
}
},
components: {}
}
</script>
<style lang="scss" rel="stylesheet/scss">
.popup-model {
background: #fff;
border-radius: 3px;
.top-p {
height: 70px;
line-height: 70px;
border-radius: 3px 3px 0 0;
padding: 0 20px;
>span {
font-size: 20px;
}
}
.bottom-p {
text-align: right;
height: 72px;
line-height: 72px;
border-radius: 0 0 3px 3px;
padding: 0 20px;
}
.content-p {
min-width: 520px;
min-height: 100px;
}
}
</style>

9
dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

@ -109,6 +109,15 @@ const menu = {
icon: 'el-icon-warning', icon: 'el-icon-warning',
children: [] children: []
}, },
{
name: `${i18n.$t('Warning instance manage')}`,
id: 2,
path: 'warning-instance-manage',
isOpen: true,
enabled: true,
icon: 'ri-spam-fill',
children: []
},
{ {
name: `${i18n.$t('Worker group manage')}`, name: `${i18n.$t('Worker group manage')}`,
id: 4, id: 4,

5
dolphinscheduler-ui/src/js/module/components/transfer/resource.vue

@ -74,8 +74,8 @@
resourceData: Object resourceData: Object
}, },
created () { created () {
let file = this.fileSourceList let file = this.resourceData.fileSourceList
let udf = this.udfSourceList let udf = this.resourceData.udfSourceList
this.diGuiTree(file) this.diGuiTree(file)
this.diGuiTree(udf) this.diGuiTree(udf)
this.fileList = file this.fileList = file
@ -218,7 +218,6 @@
delete item.children delete item.children
}, },
close () { close () {
console.log(888)
this.$emit('closeAuthResource') this.$emit('closeAuthResource')
} }
}, },

9
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -184,15 +184,14 @@ export default {
'Last heartbeat time': 'Last heartbeat time', 'Last heartbeat time': 'Last heartbeat time',
'Edit Tenant': 'Edit Tenant', 'Edit Tenant': 'Edit Tenant',
'OS Tenant Code': 'OS Tenant Code', 'OS Tenant Code': 'OS Tenant Code',
Queue: 'Yarn Queue',
'Tenant Name': 'Tenant Name', 'Tenant Name': 'Tenant Name',
Queue: 'Yarn Queue',
'Please select a queue': 'default is tenant association queue', 'Please select a queue': 'default is tenant association queue',
'Please enter the os tenant code in English': 'Please enter the os tenant code in English', 'Please enter the os tenant code in English': 'Please enter the os tenant code in English',
'Please enter os tenant code in English': 'Please enter os tenant code in English', 'Please enter os tenant code in English': 'Please enter os tenant code in English',
'Please enter os tenant code': 'Please enter os tenant code', 'Please enter os tenant code': 'Please enter os tenant code',
'Please enter tenant Name': 'Please enter tenant Name', 'Please enter tenant Name': 'Please enter tenant Name',
'The os tenant code. Only letters or a combination of letters and numbers are allowed': 'The os tenant code. Only letters or a combination of letters and numbers are allowed', 'The os tenant code. Only letters or a combination of letters and numbers are allowed': 'The os tenant code. Only letters or a combination of letters and numbers are allowed',
'The os tenant code cannot be all numbers': 'The os tenant code cannot be all numbers',
'Edit User': 'Edit User', 'Edit User': 'Edit User',
Tenant: 'Tenant', Tenant: 'Tenant',
Email: 'Email', Email: 'Email',
@ -210,9 +209,14 @@ export default {
'Please select UDF resources directory': 'Please select UDF resources directory', 'Please select UDF resources directory': 'Please select UDF resources directory',
'Edit alarm group': 'Edit alarm group', 'Edit alarm group': 'Edit alarm group',
'Create alarm group': 'Create alarm group', 'Create alarm group': 'Create alarm group',
'Create Alarm Instance': 'Create Alarm Instance',
'Edit Alarm Instance': 'Edit Alarm Instance',
'Group Name': 'Group Name', 'Group Name': 'Group Name',
'Alarm instance name': 'Alarm instance name',
'Select plugin': 'Select plugin',
'Please enter group name': 'Please enter group name', 'Please enter group name': 'Please enter group name',
'Group Type': 'Group Type', 'Group Type': 'Group Type',
'Alarm plugin instance': 'Alarm plugin instance',
Remarks: 'Remarks', Remarks: 'Remarks',
SMS: 'SMS', SMS: 'SMS',
'Managing Users': 'Managing Users', 'Managing Users': 'Managing Users',
@ -370,6 +374,7 @@ export default {
'Process definition': 'Process definition', 'Process definition': 'Process definition',
'Task record': 'Task record', 'Task record': 'Task record',
'Warning group manage': 'Warning group manage', 'Warning group manage': 'Warning group manage',
'Warning instance manage': 'Warning instance manage',
'Servers manage': 'Servers manage', 'Servers manage': 'Servers manage',
'UDF manage': 'UDF manage', 'UDF manage': 'UDF manage',
'Resource manage': 'Resource manage', 'Resource manage': 'Resource manage',

6
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -209,9 +209,14 @@ export default {
'Please select UDF resources directory': '请选择UDF资源目录', 'Please select UDF resources directory': '请选择UDF资源目录',
'Edit alarm group': '编辑告警组', 'Edit alarm group': '编辑告警组',
'Create alarm group': '创建告警组', 'Create alarm group': '创建告警组',
'Create Alarm Instance': '创建告警实例',
'Edit Alarm Instance': '编辑告警实例',
'Group Name': '组名称', 'Group Name': '组名称',
'Alarm instance name': '告警实例名称',
'Select plugin': '选择插件',
'Please enter group name': '请输入组名称', 'Please enter group name': '请输入组名称',
'Group Type': '组类型', 'Group Type': '组类型',
'Alarm plugin instance': '告警插件实例',
Remarks: '备注', Remarks: '备注',
SMS: '短信', SMS: '短信',
'Managing Users': '管理用户', 'Managing Users': '管理用户',
@ -369,6 +374,7 @@ export default {
'Process definition': '工作流定义', 'Process definition': '工作流定义',
'Task record': '任务记录', 'Task record': '任务记录',
'Warning group manage': '告警组管理', 'Warning group manage': '告警组管理',
'Warning instance manage': '告警实例管理',
'Servers manage': '服务管理', 'Servers manage': '服务管理',
'UDF manage': 'UDF管理', 'UDF manage': 'UDF管理',
'Resource manage': '资源管理', 'Resource manage': '资源管理',

4
dolphinscheduler-ui/src/js/module/io/index.js

@ -84,6 +84,10 @@ io.interceptors.request.use(
_t: Math.random() _t: Math.random()
}) })
} }
config.headers = config.headers || {}
const language = cookies.get('language')
if (language) config.headers.language = language
if (sIdCookie) config.headers.sessionId = sIdCookie
return config return config
} }
}, error => { }, error => {

4
dolphinscheduler-ui/src/sass/common/index.scss

@ -359,7 +359,9 @@ body::-webkit-scrollbar-thumb {
max-height: 200px; max-height: 200px;
overflow: auto; overflow: auto;
} }
.el-dialog__body {
padding: 10px;
}

3
pom.xml

@ -81,7 +81,7 @@
<slf4j.log4j12.version>1.7.5</slf4j.log4j12.version> <slf4j.log4j12.version>1.7.5</slf4j.log4j12.version>
<commons.collections.version>3.2.2</commons.collections.version> <commons.collections.version>3.2.2</commons.collections.version>
<commons.httpclient>3.0.1</commons.httpclient> <commons.httpclient>3.0.1</commons.httpclient>
<commons.beanutils.version>1.7.0</commons.beanutils.version> <commons.beanutils.version>1.9.4</commons.beanutils.version>
<commons.configuration.version>1.10</commons.configuration.version> <commons.configuration.version>1.10</commons.configuration.version>
<commons.email.version>1.5</commons.email.version> <commons.email.version>1.5</commons.email.version>
<poi.version>3.17</poi.version> <poi.version>3.17</poi.version>
@ -776,6 +776,7 @@
<include>**/api/enums/StatusTest.java</include> <include>**/api/enums/StatusTest.java</include>
<include>**/api/exceptions/ApiExceptionHandlerTest.java</include> <include>**/api/exceptions/ApiExceptionHandlerTest.java</include>
<include>**/api/exceptions/ServiceExceptionTest.java</include> <include>**/api/exceptions/ServiceExceptionTest.java</include>
<include>**/api/interceptor/LocaleChangeInterceptorTest.java</include>
<include>**/api/interceptor/LoginHandlerInterceptorTest.java</include> <include>**/api/interceptor/LoginHandlerInterceptorTest.java</include>
<include>**/api/security/impl/pwd/PasswordAuthenticatorTest.java</include> <include>**/api/security/impl/pwd/PasswordAuthenticatorTest.java</include>
<include>**/api/security/impl/ldap/LdapAuthenticatorTest.java</include> <include>**/api/security/impl/ldap/LdapAuthenticatorTest.java</include>

2
tools/dependencies/known-dependencies.txt

@ -24,7 +24,7 @@ commons-compress-1.4.1.jar
commons-compiler-3.0.16.jar commons-compiler-3.0.16.jar
commons-configuration-1.10.jar commons-configuration-1.10.jar
commons-daemon-1.0.13.jar commons-daemon-1.0.13.jar
commons-beanutils-1.7.0.jar commons-beanutils-1.9.4.jar
commons-dbcp-1.4.jar commons-dbcp-1.4.jar
commons-httpclient-3.0.1.jar commons-httpclient-3.0.1.jar
commons-io-2.4.jar commons-io-2.4.jar

Loading…
Cancel
Save