Browse Source

Merge pull request #3 from apache/dev

merge
pull/2/head
Tboy 5 years ago committed by GitHub
parent
commit
13cf19cf1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
  2. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java
  3. 2
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java
  4. 12
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  5. 4
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MonitorService.java
  6. 7
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZookeeperMonitor.java
  7. 2
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java
  8. 125
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java
  9. 170
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AlertGroupControllerTest.java
  10. 86
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataAnalysisControllerTest.java
  11. 196
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataSourceControllerTest.java
  12. 65
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ExecutorControllerTest.java
  13. 39
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoggerControllerTest.java
  14. 26
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoginControllerTest.java
  15. 58
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/MonitorControllerTest.java
  16. 275
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java
  17. 153
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceControllerTest.java
  18. 166
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java
  19. 17
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java
  20. 382
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ResourcesControllerTest.java
  21. 141
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/SchedulerControllerTest.java
  22. 8
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TaskInstanceControllerTest.java
  23. 94
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TaskRecordControllerTest.java
  24. 107
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TenantControllerTest.java
  25. 222
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java
  26. 102
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkerGroupControllerTest.java
  27. 32
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/enums/ExecuteTypeTest.java
  28. 17
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/enums/StatusTest.java
  29. 5
      dolphinscheduler-common/pom.xml
  30. 24
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
  31. 2
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/CommandType.java
  32. 2
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/ExecutionStatus.java
  33. 2
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/TaskRecordStatus.java
  34. 2
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/model/Server.java
  35. 47
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/queue/TaskQueueZkImpl.java
  36. 39
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java
  37. 288
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/Preconditions.java
  38. 35
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/AbstractListener.java
  39. 121
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/AbstractZKClient.java
  40. 48
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/DefaultEnsembleProvider.java
  41. 82
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperCachedOperator.java
  42. 71
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperConfig.java
  43. 232
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperOperator.java
  44. 19
      dolphinscheduler-common/src/main/resources/zookeeper.properties
  45. 16
      dolphinscheduler-dist/release-docs/LICENSE
  46. 45
      dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-jquery-ui
  47. 21
      dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-js-cookie
  48. 9
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java
  49. 71
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/SparkArgsUtils.java
  50. 9
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java
  51. 148
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/zk/ZKMasterClient.java
  52. 104
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/zk/ZKWorkerClient.java
  53. 5
      dolphinscheduler-server/src/main/resources/application-master.properties
  54. 3
      dolphinscheduler-server/src/main/resources/application-worker.properties
  55. 128
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/utils/SparkArgsUtilsTest.java
  56. 21
      dolphinscheduler-ui/build/config.js
  57. 16
      dolphinscheduler-ui/package.json
  58. 4
      dolphinscheduler-ui/src/3rdcss/animate.css
  59. 5
      dolphinscheduler-ui/src/3rdcss/bootstrap.min.css
  60. 4
      dolphinscheduler-ui/src/3rdcss/codemirror.min.css
  61. 4
      dolphinscheduler-ui/src/3rdcss/jsplumbtoolkit-defaults.min.css
  62. 4
      dolphinscheduler-ui/src/3rdcss/mdn-like.min.css
  63. 1
      dolphinscheduler-ui/src/3rdcss/normalize.min.css
  64. 2
      dolphinscheduler-ui/src/3rdcss/reset.css
  65. 4
      dolphinscheduler-ui/src/3rdcss/show-hint.min.css
  66. 5
      dolphinscheduler-ui/src/3rdcss/vs.min.css
  67. 7
      dolphinscheduler-ui/src/3rdjs/bootstrap.min.js
  68. 4
      dolphinscheduler-ui/src/3rdjs/canvg.min.js
  69. 7
      dolphinscheduler-ui/src/3rdjs/clipboard.min.js
  70. 4
      dolphinscheduler-ui/src/3rdjs/codemirror.min.js
  71. 8
      dolphinscheduler-ui/src/3rdjs/d3.min.js
  72. 1
      dolphinscheduler-ui/src/3rdjs/dayjs.min.js
  73. 21
      dolphinscheduler-ui/src/3rdjs/echarts.min.js
  74. 7
      dolphinscheduler-ui/src/3rdjs/es5-sham.min.js
  75. 7
      dolphinscheduler-ui/src/3rdjs/es5-shim.min.js
  76. 8
      dolphinscheduler-ui/src/3rdjs/html2canvas.min.js
  77. 13
      dolphinscheduler-ui/src/3rdjs/jquery-ui.min.js
  78. 2
      dolphinscheduler-ui/src/3rdjs/jquery.min.js
  79. 10
      dolphinscheduler-ui/src/3rdjs/jsplumb.min.js
  80. 138
      dolphinscheduler-ui/src/3rdjs/lodash.min.js
  81. 4
      dolphinscheduler-ui/src/3rdjs/python.min.js
  82. 4
      dolphinscheduler-ui/src/3rdjs/shell.min.js
  83. 4
      dolphinscheduler-ui/src/3rdjs/show-hint.min.js
  84. 4
      dolphinscheduler-ui/src/3rdjs/sql-hint.min.js
  85. 4
      dolphinscheduler-ui/src/3rdjs/sql.min.js
  86. 4
      dolphinscheduler-ui/src/3rdjs/textile.min.js
  87. 6
      dolphinscheduler-ui/src/3rdjs/vue-router.min.js
  88. 10552
      dolphinscheduler-ui/src/3rdjs/vue.js
  89. 6
      dolphinscheduler-ui/src/3rdjs/vuex.min.js
  90. 4
      dolphinscheduler-ui/src/3rdjs/xml-hint.min.js
  91. 4
      dolphinscheduler-ui/src/3rdjs/xml.min.js
  92. 6
      dolphinscheduler-ui/src/js/conf/home/index.js
  93. 2
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/timeoutAlarm.vue
  94. 4
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/http.vue
  95. 1
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/dragZoom.js
  96. 6
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/jsPlumbHandle.js
  97. 1
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/util.js
  98. 1
      dolphinscheduler-ui/src/js/conf/home/pages/monitor/pages/servers/_source/gauge.vue
  99. 9
      dolphinscheduler-ui/src/js/conf/home/pages/monitor/pages/servers/_source/gaugeOption.js
  100. 4
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  101. Some files were not shown because too many files have changed in this diff Show More

1
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java

@ -26,7 +26,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@ServletComponentScan
@ComponentScan("org.apache.dolphinscheduler")
@EnableSwagger2
public class ApiApplicationServer extends SpringBootServletInitializer {
public static void main(String[] args) {

3
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/ServiceModelToSwagger2MapperImpl.java

@ -16,12 +16,12 @@
*/
package org.apache.dolphinscheduler.api.configuration;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import io.swagger.models.*;
import io.swagger.models.parameters.Parameter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Primary;
import org.springframework.context.i18n.LocaleContextHolder;
@ -41,6 +41,7 @@ import static com.google.common.collect.Maps.newTreeMap;
*/
@Component(value = "ServiceModelToSwagger2Mapper")
@Primary
@ConditionalOnWebApplication
public class ServiceModelToSwagger2MapperImpl extends ServiceModelToSwagger2Mapper {

2
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/SwaggerConfig.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.configuration;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -37,6 +38,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@ConditionalOnWebApplication
public class SwaggerConfig implements WebMvcConfigurer {
@Bean

12
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -248,8 +248,8 @@ public enum Status {
KERBEROS_STARTUP_STATE(100001,"get kerberos startup state error"),
;
private int code;
private String msg;
private final int code;
private final String msg;
private Status(int code, String msg) {
this.code = code;
@ -260,15 +260,7 @@ public enum Status {
return this.code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

4
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/MonitorService.java

@ -39,6 +39,8 @@ import java.util.Map;
@Service
public class MonitorService extends BaseService{
@Autowired
private ZookeeperMonitor zookeeperMonitor;
@Autowired
private MonitorDBDao monitorDBDao;
@ -86,7 +88,7 @@ public class MonitorService extends BaseService{
public Map<String,Object> queryZookeeperState(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<ZookeeperRecord> zookeeperRecordList = ZookeeperMonitor.zookeeperInfoList();
List<ZookeeperRecord> zookeeperRecordList = zookeeperMonitor.zookeeperInfoList();
result.put(Constants.DATA_LIST, zookeeperRecordList);
putMsg(result, Status.SUCCESS);

7
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/ZookeeperMonitor.java

@ -23,6 +23,7 @@ import org.apache.dolphinscheduler.dao.entity.ZookeeperRecord;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
@ -32,17 +33,17 @@ import java.util.List;
/**
* monitor zookeeper info
*/
@Component
public class ZookeeperMonitor extends AbstractZKClient{
private static final Logger LOG = LoggerFactory.getLogger(ZookeeperMonitor.class);
private static final String zookeeperList = AbstractZKClient.getZookeeperQuorum();
/**
*
* @return zookeeper info list
*/
public static List<ZookeeperRecord> zookeeperInfoList(){
String zookeeperServers = zookeeperList.replaceAll("[\\t\\n\\x0B\\f\\r]", "");
public List<ZookeeperRecord> zookeeperInfoList(){
String zookeeperServers = getZookeeperQuorum().replaceAll("[\\t\\n\\x0B\\f\\r]", "");
try{
return zookeeperInfoList(zookeeperServers);
}catch(Exception e){

2
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java

@ -80,4 +80,4 @@ public class AbstractControllerTest {
Assert.assertTrue(StringUtils.isNotEmpty(session));
}
}
}

125
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java

@ -0,0 +1,125 @@
/*
* 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.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class AccessTokenControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(AccessTokenControllerTest.class);
@Test
public void testCreateToken() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","4");
paramsMap.add("expireTime","2019-12-18 00:00:00");
paramsMap.add("token","607f5aeaaa2093dbdff5d5522ce00510");
MvcResult mvcResult = mockMvc.perform(post("/access-token/create")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGenerateToken() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","4");
paramsMap.add("expireTime","2019-12-28 00:00:00");
MvcResult mvcResult = mockMvc.perform(post("/access-token/generate")
.header("sessionId", "5925a115-1691-47e0-9c46-4c7da03f6bbd")
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryAccessTokenList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","20");
paramsMap.add("searchVal","");
MvcResult mvcResult = mockMvc.perform(get("/access-token/list-paging")
.header("sessionId", "5925a115-1691-47e0-9c46-4c7da03f6bbd")
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDelAccessTokenById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","13");
MvcResult mvcResult = mockMvc.perform(post("/access-token/delete")
.header("sessionId", "5925a115-1691-47e0-9c46-4c7da03f6bbd")
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateToken() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","12");
paramsMap.add("userId","4");
paramsMap.add("expireTime","2019-12-20 00:00:00");
paramsMap.add("token","cxctoken123update");
MvcResult mvcResult = mockMvc.perform(post("/access-token/update")
.header("sessionId", "5925a115-1691-47e0-9c46-4c7da03f6bbd")
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

170
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AlertGroupControllerTest.java

@ -0,0 +1,170 @@
/*
* 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.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.AlertType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class AlertGroupControllerTest extends AbstractControllerTest{
private static final Logger logger = LoggerFactory.getLogger(AlertGroupController.class);
@Test
public void testCreateAlertgroup() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("groupName","cxc test group name");
paramsMap.add("groupType", AlertType.EMAIL.toString());
paramsMap.add("description","cxc junit 测试告警描述");
MvcResult mvcResult = mockMvc.perform(post("/alert-group/create")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(get("/alert-group/list")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo","1");
paramsMap.add("searchVal", AlertType.EMAIL.toString());
paramsMap.add("pageSize","1");
MvcResult mvcResult = mockMvc.perform(get("/alert-group/list-paging")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateAlertgroup() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","22");
paramsMap.add("groupName", "hd test group name");
paramsMap.add("groupType",AlertType.EMAIL.toString());
paramsMap.add("description","update alter group");
MvcResult mvcResult = mockMvc.perform(post("/alert-group/update")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyGroupName() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("groupName","hd test group name");
MvcResult mvcResult = mockMvc.perform(get("/alert-group/verify-group-name")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.ALERT_GROUP_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyGroupNameNotExit() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("groupName","cxc test group name");
MvcResult mvcResult = mockMvc.perform(get("/alert-group/verify-group-name")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGrantUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("alertgroupId","2");
paramsMap.add("userIds","2");
MvcResult mvcResult = mockMvc.perform(post("/alert-group/grant-user")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDelAlertgroupById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","22");
MvcResult mvcResult = mockMvc.perform(post("/alert-group/delete")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

86
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataAnalysisControllerTest.java

@ -41,32 +41,40 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Ignore
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataAnalysisControllerTest {
public class DataAnalysisControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(DataAnalysisControllerTest.class);
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Test
public void testCountTaskState() throws Exception {
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-12-01 00:00:00");
paramsMap.add("endDate","2019-12-28 00:00:00");
paramsMap.add("projectId","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/task-state-count")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void countTaskState() throws Exception {
public void testCountProcessInstanceState() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-02-01 00:00:00");
paramsMap.add("endDate","2019-02-28 00:00:00");
paramsMap.add("projectId","21");
paramsMap.add("startDate","2019-12-01 00:00:00");
paramsMap.add("endDate","2019-12-28 00:00:00");
paramsMap.add("projectId","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/task-state-count")
.header("sessionId", "08fae8bf-fe2d-4fc0-8129-23c37fbfac82")
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/process-state-count")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
@ -77,15 +85,47 @@ public class DataAnalysisControllerTest {
}
@Test
public void countProcessInstanceState() throws Exception {
public void testCountDefinitionByUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-02-01 00:00:00");
paramsMap.add("endDate","2019-02-28 00:00:00");
paramsMap.add("projectId","21");
paramsMap.add("projectId","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/process-state-count")
.header("sessionId", "08fae8bf-fe2d-4fc0-8129-23c37fbfac82")
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/define-user-count")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testCountCommandState() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-12-01");
paramsMap.add("endDate","2019-12-15");
paramsMap.add("projectId","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/command-state-count")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testCountQueueState() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/queue-count")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
@ -94,4 +134,4 @@ public class DataAnalysisControllerTest {
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

196
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataSourceControllerTest.java

@ -41,10 +41,67 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class DataSourceControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(DataSourceControllerTest.class);
@Ignore
@Test
public void testCreateDataSource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","mysql");
paramsMap.add("node","mysql data source test");
paramsMap.add("type","MYSQL");
paramsMap.add("host","192.168.xxxx.xx");
paramsMap.add("port","3306");
paramsMap.add("principal","");
paramsMap.add("database","dolphinscheduler");
paramsMap.add("userName","root");
paramsMap.add("password","root@123");
paramsMap.add("other","");
MvcResult mvcResult = mockMvc.perform(post("/datasources/create")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void queryDataSource() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/datasources/list").header("sessionId", sessionId).param("type","HIVE"))
public void testUpdateDataSource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","2");
paramsMap.add("name","mysql");
paramsMap.add("node","mysql data source test");
paramsMap.add("type","MYSQL");
paramsMap.add("host","192.168.xxxx.xx");
paramsMap.add("port","3306");
paramsMap.add("principal","");
paramsMap.add("database","dolphinscheduler");
paramsMap.add("userName","root");
paramsMap.add("password","root@123");
paramsMap.add("other","");
MvcResult mvcResult = mockMvc.perform(post("/datasources/update")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryDataSource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","2");
MvcResult mvcResult = mockMvc.perform(post("/datasources/update-ui")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
@ -53,10 +110,44 @@ public class DataSourceControllerTest extends AbstractControllerTest{
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void testQueryDataSourceList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("type","MYSQL");
MvcResult mvcResult = mockMvc.perform(get("/datasources/list")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void connectDataSource() throws Exception {
public void testQueryDataSourceListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("searchVal","mysql");
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","1");
MvcResult mvcResult = mockMvc.perform(get("/datasources/list-paging")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void testConnectDataSource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","hive data source");
paramsMap.add("type","HIVE");
@ -68,7 +159,72 @@ public class DataSourceControllerTest extends AbstractControllerTest{
paramsMap.add("other","");
MvcResult mvcResult = mockMvc.perform(post("/datasources/connect")
.header("sessionId", sessionId)
.params(paramsMap))
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testConnectionTest() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","2");
MvcResult mvcResult = mockMvc.perform(get("/datasources/connect-by-id")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyDataSourceName() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","mysql");
MvcResult mvcResult = mockMvc.perform(get("/datasources/verify-name")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testAuthedDatasource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","2");
MvcResult mvcResult = mockMvc.perform(get("/datasources/authed-datasource")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUnauthDatasource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","2");
MvcResult mvcResult = mockMvc.perform(get("/datasources/unauth-datasource")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
@ -78,4 +234,32 @@ public class DataSourceControllerTest extends AbstractControllerTest{
}
}
@Test
public void testGetKerberosStartupState() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/datasources/kerberos-startup-state")
.header("sessionId", sessionId))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDelete() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","16");
MvcResult mvcResult = mockMvc.perform(get("/datasources/delete")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

65
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ExecutorControllerTest.java

@ -16,8 +16,11 @@
*/
package org.apache.dolphinscheduler.api.controller;
import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Ignore;
@ -37,17 +40,64 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
/**
* executor controller test
*/
@Ignore
public class ExecutorControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(ExecutorControllerTest.class);
@Ignore
@Test
public void testStartProcessInstance() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","40");
paramsMap.add("scheduleTime","");
paramsMap.add("failureStrategy", String.valueOf(FailureStrategy.CONTINUE));
paramsMap.add("startNodeList","");
paramsMap.add("taskDependType","");
paramsMap.add("execType","");
paramsMap.add("warningType", String.valueOf(WarningType.NONE));
paramsMap.add("warningGroupId","");
paramsMap.add("receivers","");
paramsMap.add("receiversCc","");
paramsMap.add("runMode","");
paramsMap.add("processInstancePriority","");
paramsMap.add("workerGroupId","");
paramsMap.add("timeout","");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/executors/start-process-instance","cxc_1113")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void testExecute() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processInstanceId","40");
paramsMap.add("executeType",String.valueOf(ExecuteType.NONE));
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/executors/execute","cxc_1113")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void startCheckProcessDefinition() throws Exception {
public void testStartCheckProcessDefinition() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/executors/start-check","project_test1")
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/executors/start-check","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processDefinitionId","226"))
.param("processDefinitionId","40"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
@ -57,11 +107,10 @@ public class ExecutorControllerTest extends AbstractControllerTest{
}
@Test
public void getReceiverCc() throws Exception {
public void testGetReceiverCc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
//paramsMap.add("processDefinitionId","4");
paramsMap.add("processInstanceId","13");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/executors/get-receiver-cc","li_sql_test")
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/executors/get-receiver-cc","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
@ -71,4 +120,4 @@ public class ExecutorControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

39
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoggerControllerTest.java

@ -20,39 +20,64 @@ import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
/**
* logger controller test
*/
@Ignore
public class LoggerControllerTest extends AbstractControllerTest {
private static Logger logger = LoggerFactory.getLogger(DataAnalysisControllerTest.class);
private static Logger logger = LoggerFactory.getLogger(LoggerControllerTest.class);
@Test
public void queryLog() throws Exception {
public void testQueryLog() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("taskInstId","-1");
paramsMap.add("taskInstId","1501");
paramsMap.add("skipLineNum","0");
paramsMap.add("limit","1000");
MvcResult mvcResult = mockMvc.perform(get("/log/detail")
.header("sessionId", sessionId)
.params(paramsMap))
// .andExpect(status().isOk())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDownloadTaskLog() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("taskInstId","1501");
MvcResult mvcResult = mockMvc.perform(get("/log/download-log")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
// .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TASK_INSTANCE_NOT_FOUND.getCode(),result.getCode().intValue());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

26
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoginControllerTest.java

@ -40,12 +40,11 @@ public class LoginControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(SchedulerControllerTest.class);
@Test
public void login() throws Exception {
public void testLogin() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userName","admin");
paramsMap.add("userPassword","dolphinscheduler123");
paramsMap.add("userName","cxc");
paramsMap.add("userPassword","123456");
MvcResult mvcResult = mockMvc.perform(post("/login")
.params(paramsMap))
@ -57,4 +56,21 @@ public class LoginControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testSignOut() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(post("/signOut")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

58
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/MonitorControllerTest.java

@ -40,20 +40,35 @@ public class MonitorControllerTest extends AbstractControllerTest {
@Test
public void listMaster() throws Exception {
public void testListMaster() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/monitor/master/list")
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testListWorker() throws Exception {
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
MvcResult mvcResult = mockMvc.perform(get("/monitor/worker/list")
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
@ -61,38 +76,35 @@ public class MonitorControllerTest extends AbstractControllerTest {
@Test
public void queryDatabaseState() throws Exception {
public void testQueryDatabaseState() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/monitor/database")
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void queryZookeeperState() throws Exception {
public void testQueryZookeeperState() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/monitor/zookeeper/list")
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
.header(SESSION_ID, sessionId)
/* .param("type", ResourceType.FILE.name())*/ )
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

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

@ -18,8 +18,10 @@ package org.apache.dolphinscheduler.api.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,6 +30,7 @@ import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -40,7 +43,7 @@ public class ProcessDefinitionControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(ProcessDefinitionControllerTest.class);
@Test
public void createProcessDefinition() throws Exception {
public void testCreateProcessDefinition() throws Exception {
String json = "{\"globalParams\":[],\"tasks\":[{\"type\":\"SHELL\",\"id\":\"tasks-36196\",\"name\":\"ssh_test1\",\"params\":{\"resourceList\":[],\"localParams\":[],\"rawScript\":\"aa=\\\"1234\\\"\\necho ${aa}\"},\"desc\":\"\",\"runFlag\":\"NORMAL\",\"dependence\":{},\"maxRetryTimes\":\"0\",\"retryInterval\":\"1\",\"timeout\":{\"strategy\":\"\",\"interval\":null,\"enable\":false},\"taskInstancePriority\":\"MEDIUM\",\"workerGroupId\":-1,\"preTasks\":[]}],\"tenantId\":-1,\"timeout\":0}";
String locations = "{\"tasks-36196\":{\"name\":\"ssh_test1\",\"targetarr\":\"\",\"x\":141,\"y\":70}}";
@ -49,9 +52,9 @@ public class ProcessDefinitionControllerTest extends AbstractControllerTest{
paramsMap.add("processDefinitionJson",json);
paramsMap.add("locations", locations);
paramsMap.add("connects", "[]");
paramsMap.add("desc", "desc test");
paramsMap.add("description", "desc test");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/process/save","project_test1")
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/process/save","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
@ -59,7 +62,269 @@ public class ProcessDefinitionControllerTest extends AbstractControllerTest{
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.PROJECT_NOT_FOUNT.getCode(),result.getCode().intValue());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testVerifyProccessDefinitionName() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","dag_test");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/verify-name","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.PROCESS_INSTANCE_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyProccessDefinitionNameNotExit() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","dag_test_1");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/verify-name","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void UpdateProccessDefinition() throws Exception {
String json = "{\"globalParams\":[],\"tasks\":[{\"type\":\"SHELL\",\"id\":\"tasks-36196\",\"name\":\"ssh_test1\",\"params\":{\"resourceList\":[],\"localParams\":[],\"rawScript\":\"aa=\\\"1234\\\"\\necho ${aa}\"},\"desc\":\"\",\"runFlag\":\"NORMAL\",\"dependence\":{},\"maxRetryTimes\":\"0\",\"retryInterval\":\"1\",\"timeout\":{\"strategy\":\"\",\"interval\":null,\"enable\":false},\"taskInstancePriority\":\"MEDIUM\",\"workerGroupId\":-1,\"preTasks\":[]}],\"tenantId\":-1,\"timeout\":0}";
String locations = "{\"tasks-36196\":{\"name\":\"ssh_test1\",\"targetarr\":\"\",\"x\":141,\"y\":70}}";
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","dag_test_update");
paramsMap.add("id","91");
paramsMap.add("processDefinitionJson",json);
paramsMap.add("locations", locations);
paramsMap.add("connects", "[]");
paramsMap.add("description", "desc test update");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/process/update","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testReleaseProccessDefinition() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processId","91");
paramsMap.add("releaseState",String.valueOf(ReleaseState.OFFLINE));
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/process/release","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProccessDefinitionById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processId","91");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/select-by-id","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProccessDefinitionList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/list","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProcessDefinitionListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo","1");
paramsMap.add("searchVal","test");
paramsMap.add("userId","");
paramsMap.add("pageSize", "1");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/list-paging","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testViewTree() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processId","91");
paramsMap.add("limit","30");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/view-tree","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGetNodeListByDefinitionId() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","40");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/gen-task-list","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGetNodeListByDefinitionIdList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionIdList","40,90,91");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/get-task-list","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void testExportProcessDefinitionById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","91");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/export","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
// .andExpect(status().isOk())
// .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProccessDefinitionAllByProjectId() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","9");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/queryProccessDefinitionAllByProjectId","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteProcessDefinitionById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","73");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/delete","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testBatchDeleteProcessDefinitionByIds() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionIds","54,62");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/process/batch-delete","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

153
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessInstanceControllerTest.java

@ -18,6 +18,7 @@ package org.apache.dolphinscheduler.api.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
@ -25,8 +26,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -36,13 +40,35 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class ProcessInstanceControllerTest extends AbstractControllerTest {
private static Logger logger = LoggerFactory.getLogger(ProcessInstanceControllerTest.class);
@Test
public void testQueryProcessInstanceList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId", "91");
paramsMap.add("searchVal", "cxc");
paramsMap.add("stateType", String.valueOf(ExecutionStatus.SUCCESS));
paramsMap.add("host", "192.168.1.13");
paramsMap.add("startDate", "2019-12-15 00:00:00");
paramsMap.add("endDate", "2019-12-16 00:00:00");
paramsMap.add("pageNo", "2");
paramsMap.add("pageSize", "2");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/list-paging","cxc_1113")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void queryTaskListByProcessId() throws Exception {
public void testQueryTaskListByProcessId() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/task-list-by-process-id","project_test1")
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/task-list-by-process-id","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processInstanceId","-1"))
.param("processInstanceId","1203"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
@ -51,4 +77,123 @@ public class ProcessInstanceControllerTest extends AbstractControllerTest {
Assert.assertEquals(Status.PROJECT_NOT_FOUNT,result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testUpdateProcessInstance() throws Exception {
String json = "{\"globalParams\":[],\"tasks\":[{\"type\":\"SHELL\",\"id\":\"tasks-36196\",\"name\":\"ssh_test1\",\"params\":{\"resourceList\":[],\"localParams\":[],\"rawScript\":\"aa=\\\"1234\\\"\\necho ${aa}\"},\"desc\":\"\",\"runFlag\":\"NORMAL\",\"dependence\":{},\"maxRetryTimes\":\"0\",\"retryInterval\":\"1\",\"timeout\":{\"strategy\":\"\",\"interval\":null,\"enable\":false},\"taskInstancePriority\":\"MEDIUM\",\"workerGroupId\":-1,\"preTasks\":[]}],\"tenantId\":-1,\"timeout\":0}";
String locations = "{\"tasks-36196\":{\"name\":\"ssh_test1\",\"targetarr\":\"\",\"x\":141,\"y\":70}}";
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processInstanceJson", json);
paramsMap.add("processInstanceId", "91");
paramsMap.add("scheduleTime", "2019-12-15 00:00:00");
paramsMap.add("syncDefine", "false");
paramsMap.add("locations", locations);
paramsMap.add("connects", "[]");
// paramsMap.add("flag", "2");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/instance/update","cxc_1113")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProcessInstanceById() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/select-by-id","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processInstanceId","1203"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQuerySubProcessInstanceByTaskId() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/select-sub-process","cxc_1113")
.header(SESSION_ID, sessionId)
.param("taskId","1203"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TASK_INSTANCE_NOT_EXISTS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryParentInstanceBySubId() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/select-parent-process","cxc_1113")
.header(SESSION_ID, sessionId)
.param("subId","1204"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.PROCESS_INSTANCE_NOT_SUB_PROCESS_INSTANCE.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testViewVariables() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/view-variables","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processInstanceId","1204"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteProcessInstanceById() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/delete","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processInstanceId","1204"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testBatchDeleteProcessInstanceByIds() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/instance/batch-delete","cxc_1113")
.header(SESSION_ID, sessionId)
.param("processInstanceIds","1205,1206"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.DELETE_PROCESS_INSTANCE_BY_ID_ERROR.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

166
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java

@ -20,6 +20,7 @@ import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,6 +29,9 @@ import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import javax.ws.rs.POST;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -36,11 +40,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* project controller
*/
public class ProjectControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(ProcessInstanceControllerTest.class);
private static Logger logger = LoggerFactory.getLogger(ProjectControllerTest.class);
@Test
public void createProject() throws Exception {
public void testCreateProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectName","project_test1");
@ -57,4 +61,160 @@ public class ProjectControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testUpdateProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","18");
paramsMap.add("projectName","project_test_update");
paramsMap.add("desc","the test project update");
MvcResult mvcResult = mockMvc.perform(post("/projects/update")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProjectById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","18");
MvcResult mvcResult = mockMvc.perform(get("/projects/query-by-id")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryProjectListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("searchVal","test");
paramsMap.add("pageSize","2");
paramsMap.add("pageNo","2");
MvcResult mvcResult = mockMvc.perform(get("/projects/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryUnauthorizedProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","2");
MvcResult mvcResult = mockMvc.perform(get("/projects/unauth-project")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryAuthorizedProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","2");
MvcResult mvcResult = mockMvc.perform(get("/projects/authed-project")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryAllProjectList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(get("/projects/query-project-list")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Ignore
@Test
public void testImportProcessDefinition() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("file","test");
MvcResult mvcResult = mockMvc.perform(post("/projects/import-definition")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.TEXT_PLAIN))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.IMPORT_PROCESS_DEFINE_ERROR.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","18");
MvcResult mvcResult = mockMvc.perform(get("/projects/delete")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

17
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java

@ -41,7 +41,7 @@ public class QueueControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(QueueControllerTest.class);
@Test
public void queryList() throws Exception {
public void testQueryList() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/queue/list")
.header(SESSION_ID, sessionId))
@ -55,7 +55,7 @@ public class QueueControllerTest extends AbstractControllerTest{
}
@Test
public void queryPagingList() throws Exception {
public void testQueryQueueListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
//paramsMap.add("processInstanceId","1380");
@ -74,8 +74,11 @@ public class QueueControllerTest extends AbstractControllerTest{
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void createQueue() throws Exception {
public void testCreateQueue() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("queue","ait");
@ -90,12 +93,10 @@ public class QueueControllerTest extends AbstractControllerTest{
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
// Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void updateQueue() throws Exception {
public void testUpdateQueue() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","2");
@ -114,7 +115,7 @@ public class QueueControllerTest extends AbstractControllerTest{
}
@Test
public void verifyQueue() throws Exception {
public void testVerifyQueue() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("queue","ait123");
@ -130,4 +131,4 @@ public class QueueControllerTest extends AbstractControllerTest{
//Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

382
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ResourcesControllerTest.java

@ -18,10 +18,13 @@ package org.apache.dolphinscheduler.api.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.enums.ResourceType;
import org.apache.dolphinscheduler.common.enums.UdfType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,6 +34,7 @@ import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -41,7 +45,7 @@ public class ResourcesControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(ResourcesControllerTest.class);
@Test
public void querytResourceList() throws Exception {
public void testQuerytResourceList() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/resources/list")
.header(SESSION_ID, sessionId)
@ -58,8 +62,33 @@ public class ResourcesControllerTest extends AbstractControllerTest{
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryResourceListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("type", String.valueOf(ResourceType.FILE));
paramsMap.add("pageNo", "1");
paramsMap.add("searchVal", "test");
paramsMap.add("pageSize", "1");
MvcResult mvcResult = mockMvc.perform(get("/resources/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void verifyResourceName() throws Exception {
public void testVerifyResourceName() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","list_resources_1.sh");
@ -77,4 +106,351 @@ public class ResourcesControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testViewResource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","5");
paramsMap.add("skipLineNum","2");
paramsMap.add("limit","100");
MvcResult mvcResult = mockMvc.perform(get("/resources/view")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testOnlineCreateResource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("type", String.valueOf(ResourceType.FILE));
paramsMap.add("fileName","test_file_1");
paramsMap.add("suffix","sh");
paramsMap.add("description","test");
paramsMap.add("content","echo 1111");
MvcResult mvcResult = mockMvc.perform(post("/resources/online-create")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateResourceContent() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "1");
paramsMap.add("content","echo test_1111");
MvcResult mvcResult = mockMvc.perform(post("/resources/update-content")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDownloadResource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "5");
MvcResult mvcResult = mockMvc.perform(get("/resources/download")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testCreateUdfFunc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("type", String.valueOf(UdfType.HIVE));
paramsMap.add("funcName", "test_udf");
paramsMap.add("className", "com.test.word.contWord");
paramsMap.add("argTypes", "argTypes");
paramsMap.add("database", "database");
paramsMap.add("description", "description");
paramsMap.add("resourceId", "1");
MvcResult mvcResult = mockMvc.perform(post("/resources/udf-func/create")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testViewUIUdfFunction() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "1");
MvcResult mvcResult = mockMvc.perform(get("/resources/udf-func/update-ui")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateUdfFunc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "1");
paramsMap.add("type", String.valueOf(UdfType.HIVE));
paramsMap.add("funcName", "update_duf");
paramsMap.add("className", "com.test.word.contWord");
paramsMap.add("argTypes", "argTypes");
paramsMap.add("database", "database");
paramsMap.add("description", "description");
paramsMap.add("resourceId", "1");
MvcResult mvcResult = mockMvc.perform(post("/resources/udf-func/update")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.TENANT_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryUdfFuncList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo", "1");
paramsMap.add("searchVal", "udf");
paramsMap.add("pageSize", "1");
MvcResult mvcResult = mockMvc.perform(get("/resources/udf-func/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryResourceList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("type", String.valueOf(UdfType.HIVE));
MvcResult mvcResult = mockMvc.perform(get("/resources/udf-func/list")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyUdfFuncName() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name", "test");
MvcResult mvcResult = mockMvc.perform(get("/resources/udf-func/verify-name")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testAuthorizedFile() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId", "2");
MvcResult mvcResult = mockMvc.perform(get("/resources/authed-file")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUnauthorizedFile() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId", "2");
MvcResult mvcResult = mockMvc.perform(get("/resources/unauth-file")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testAuthorizedUDFFunction() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId", "2");
MvcResult mvcResult = mockMvc.perform(get("/resources/authed-udf-func")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUnauthUDFFunc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId", "2");
MvcResult mvcResult = mockMvc.perform(get("/resources/unauth-udf-func")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteUdfFunc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id", "1");
MvcResult mvcResult = mockMvc.perform(get("/resources/udf-func/delete")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteResource() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/resources/delete")
.header(SESSION_ID, sessionId)
.param("id", "2"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
result.getCode().equals(Status.SUCCESS.getCode());
JSONObject object = (JSONObject) JSONObject.parse(mvcResult.getResponse().getContentAsString());
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

141
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/SchedulerControllerTest.java

@ -18,6 +18,9 @@ package org.apache.dolphinscheduler.api.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
@ -25,7 +28,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -37,8 +43,116 @@ public class SchedulerControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(SchedulerControllerTest.class);
@Test
public void queryScheduleList() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/list","project_test1")
public void testCreateSchedule() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","40");
paramsMap.add("schedule","{'startTime':'2019-12-16 00:00:00','endTime':'2019-12-17 00:00:00','crontab':'0 0 6 * * ? *'}");
paramsMap.add("warningType",String.valueOf(WarningType.NONE));
paramsMap.add("warningGroupId","1");
paramsMap.add("failureStrategy",String.valueOf(FailureStrategy.CONTINUE));
paramsMap.add("receivers","");
paramsMap.add("receiversCc","");
paramsMap.add("workerGroupId","1");
paramsMap.add("processInstancePriority",String.valueOf(Priority.HIGH));
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/create","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateSchedule() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","37");
paramsMap.add("schedule","{'startTime':'2019-12-16 00:00:00','endTime':'2019-12-17 00:00:00','crontab':'0 0 7 * * ? *'}");
paramsMap.add("warningType",String.valueOf(WarningType.NONE));
paramsMap.add("warningGroupId","1");
paramsMap.add("failureStrategy",String.valueOf(FailureStrategy.CONTINUE));
paramsMap.add("receivers","");
paramsMap.add("receiversCc","");
paramsMap.add("workerGroupId","1");
paramsMap.add("processInstancePriority",String.valueOf(Priority.HIGH));
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/update","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testOnline() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","37");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/online","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testOffline() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","28");
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/offline","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryScheduleListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("processDefinitionId","40");
paramsMap.add("searchVal","test");
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","30");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/schedule/list-paging","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryScheduleList() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/list","cxc_1113")
.header(SESSION_ID, sessionId))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
@ -51,8 +165,8 @@ public class SchedulerControllerTest extends AbstractControllerTest{
@Test
public void previewSchedule() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/preview","li_test_1")
public void testPreviewSchedule() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/projects/{projectName}/schedule/preview","cxc_1113")
.header(SESSION_ID, sessionId)
.param("schedule","{'startTime':'2019-06-10 00:00:00','endTime':'2019-06-13 00:00:00','crontab':'0 0 3/6 * * ? *'}"))
.andExpect(status().isCreated())
@ -63,4 +177,21 @@ public class SchedulerControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
@Test
public void testDeleteScheduleById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("scheduleId","37");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/schedule/delete","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

8
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TaskInstanceControllerTest.java

@ -36,10 +36,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* task instance controller test
*/
public class TaskInstanceControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(SchedulerControllerTest.class);
private static Logger logger = LoggerFactory.getLogger(TaskInstanceControllerTest.class);
@Test
public void queryTaskListPaging() throws Exception {
public void testQueryTaskListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
//paramsMap.add("processInstanceId","1380");
@ -51,7 +51,7 @@ public class TaskInstanceControllerTest extends AbstractControllerTest{
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","20");
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/task-instance/list-paging","project_test1")
MvcResult mvcResult = mockMvc.perform(get("/projects/{projectName}/task-instance/list-paging","cxc_1113")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
@ -62,4 +62,4 @@ public class TaskInstanceControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

94
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TaskRecordControllerTest.java

@ -0,0 +1,94 @@
/*
* 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.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class TaskRecordControllerTest extends AbstractControllerTest {
private static final Logger logger = LoggerFactory.getLogger(TaskInstanceController.class);
@Test
public void testQueryTaskRecordListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("taskName","taskName");
paramsMap.add("state","state");
paramsMap.add("sourceTable","");
paramsMap.add("destTable","");
paramsMap.add("taskDate","");
paramsMap.add("startDate","2019-12-16 00:00:00");
paramsMap.add("endDate","2019-12-17 00:00:00");
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","30");
MvcResult mvcResult = mockMvc.perform(get("/projects/task-record/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryHistoryTaskRecordListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("taskName","taskName");
paramsMap.add("state","state");
paramsMap.add("sourceTable","");
paramsMap.add("destTable","");
paramsMap.add("taskDate","");
paramsMap.add("startDate","2019-12-16 00:00:00");
paramsMap.add("endDate","2019-12-17 00:00:00");
paramsMap.add("pageNo","1");
paramsMap.add("pageSize","30");
MvcResult mvcResult = mockMvc.perform(get("/projects/task-record/history-list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

107
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/TenantControllerTest.java

@ -25,8 +25,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -34,11 +37,93 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* tenant controller test
*/
public class TenantControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(DataAnalysisControllerTest.class);
private static Logger logger = LoggerFactory.getLogger(TenantControllerTest.class);
@Test
public void testCreateTenant() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("tenantCode","tenantCode");
paramsMap.add("tenantName","tenantName");
paramsMap.add("queueId","1");
paramsMap.add("description","tenant description");
MvcResult mvcResult = mockMvc.perform(post("/tenant/create")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryTenantlistPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo","1");
paramsMap.add("searchVal","tenant");
paramsMap.add("pageSize","30");
MvcResult mvcResult = mockMvc.perform(get("/tenant/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateTenant() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","9");
paramsMap.add("tenantCode","cxc_te");
paramsMap.add("tenantName","tenant_update_2");
paramsMap.add("queueId","1");
paramsMap.add("description","tenant description");
MvcResult mvcResult = mockMvc.perform(post("/tenant/update")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void countTaskState() throws Exception {
public void testVerifyTenantCode() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("tenantCode","cxc_test");
MvcResult mvcResult = mockMvc.perform(get("/tenant/verify-tenant-code")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryTenantlist() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/tenant/list")
.header(SESSION_ID, sessionId))
@ -46,9 +131,25 @@ public class TenantControllerTest extends AbstractControllerTest{
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteTenantById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","64");
MvcResult mvcResult = mockMvc.perform(post("/tenant/delete")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

222
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java

@ -25,8 +25,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -36,9 +39,224 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class UsersControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(QueueControllerTest.class);
@Test
public void testCreateUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userName","user_test");
paramsMap.add("userPassword","123456qwe?");
paramsMap.add("tenantId","9");
paramsMap.add("queue","1");
paramsMap.add("email","12343534@qq.com");
paramsMap.add("phone","15800000000");
MvcResult mvcResult = mockMvc.perform(post("/users/create")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUpdateUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","32");
paramsMap.add("userName","user_test");
paramsMap.add("userPassword","123456qwe?");
paramsMap.add("tenantId","9");
paramsMap.add("queue","1");
paramsMap.add("email","12343534@qq.com");
paramsMap.add("phone","15800000000");
MvcResult mvcResult = mockMvc.perform(post("/users/update")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGrantProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","32");
paramsMap.add("projectIds","3");
MvcResult mvcResult = mockMvc.perform(post("/users/grant-project")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGrantResource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","32");
paramsMap.add("resourceIds","5");
MvcResult mvcResult = mockMvc.perform(post("/users/grant-file")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGrantUDFFunc() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","32");
paramsMap.add("udfIds","5");
MvcResult mvcResult = mockMvc.perform(post("/users/grant-udf-func")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGrantDataSource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","32");
paramsMap.add("datasourceIds","5");
MvcResult mvcResult = mockMvc.perform(post("/users/grant-datasource")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testGetUserInfo() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/users/get-user-info")
.header(SESSION_ID, sessionId))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testListAll() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userName","test");
MvcResult mvcResult = mockMvc.perform(get("/users/list-all")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testAuthorizedUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("alertgroupId","1");
MvcResult mvcResult = mockMvc.perform(get("/users/authed-user")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testUnauthorizedUser() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("alertgroupId","1");
MvcResult mvcResult = mockMvc.perform(get("/users/unauth-user")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testVerifyUserName() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/users/verify-user-name")
.header(SESSION_ID, sessionId))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDelUserById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","32");
MvcResult mvcResult = mockMvc.perform(post("/users/delete")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void queryList() throws Exception {
public void testQueryList() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/users/list")
.header(SESSION_ID, sessionId))
@ -50,4 +268,4 @@ public class UsersControllerTest extends AbstractControllerTest{
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}
}

102
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkerGroupControllerTest.java

@ -0,0 +1,102 @@
/*
* 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.controller;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class WorkerGroupControllerTest extends AbstractControllerTest{
private static Logger logger = LoggerFactory.getLogger(WorkerGroupControllerTest.class);
@Test
public void testSaveWorkerGroup() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("name","cxc_work_group");
paramsMap.add("ipList","192.16.12,192.168,10,12");
MvcResult mvcResult = mockMvc.perform(post("/worker-group/save")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryAllWorkerGroupsPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("pageNo","2");
paramsMap.add("searchVal","cxc");
paramsMap.add("pageSize","2");
MvcResult mvcResult = mockMvc.perform(get("/worker-group/list-paging")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testQueryAllWorkerGroups() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(get("/worker-group/all-groups")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
@Test
public void testDeleteById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","12");
MvcResult mvcResult = mockMvc.perform(get("/worker-group/delete-by-id")
.header("sessionId", sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
}
}

32
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/enums/ExecuteTypeTest.java

@ -0,0 +1,32 @@
/*
* 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.enums;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExecuteTypeTest {
@Test
public void testGetEnum() {
assertEquals(ExecuteType.REPEAT_RUNNING, ExecuteType.getEnum(1));
assertEquals(ExecuteType.RECOVER_SUSPENDED_PROCESS, ExecuteType.getEnum(2));
assertEquals(ExecuteType.START_FAILURE_TASK_PROCESS, ExecuteType.getEnum(3));
assertEquals(ExecuteType.STOP, ExecuteType.getEnum(4));
assertEquals(ExecuteType.PAUSE, ExecuteType.getEnum(5));
}
}

17
dolphinscheduler-ui/src/sass/common/_font.scss → dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/enums/StatusTest.java

@ -14,4 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.enums;
import org.junit.Test;
import static org.junit.Assert.*;
public class StatusTest {
@Test
public void testGetCode() {
assertEquals(Status.SUCCESS.getCode(), 0);
assertNotEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR.getCode(), 0);
}
@Test
public void testGetMsg() {
assertEquals("success", Status.SUCCESS.getMsg());
}
}

5
dolphinscheduler-common/pom.xml

@ -611,5 +611,10 @@
<version>${lombok.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
</project>

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

@ -139,42 +139,50 @@ public final class Constants {
/**
* MasterServer directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_MASTERS = "zookeeper.dolphinscheduler.masters";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_MASTERS = "zookeeper.dolphinscheduler.masters";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_MASTERS = "/masters";
/**
* WorkerServer directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_WORKERS = "zookeeper.dolphinscheduler.workers";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_WORKERS = "zookeeper.dolphinscheduler.workers";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_WORKERS = "/workers";
/**
* all servers directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_DEAD_SERVERS = "zookeeper.dolphinscheduler.dead.servers";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_DEAD_SERVERS = "zookeeper.dolphinscheduler.dead.servers";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_DEAD_SERVERS = "/dead-servers";
/**
* MasterServer lock directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_MASTERS = "zookeeper.dolphinscheduler.lock.masters";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_MASTERS = "zookeeper.dolphinscheduler.lock.masters";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_MASTERS = "/lock/masters";
/**
* WorkerServer lock directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_WORKERS = "zookeeper.dolphinscheduler.lock.workers";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_WORKERS = "zookeeper.dolphinscheduler.lock.workers";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_WORKERS = "/lock/workers";
/**
* MasterServer failover directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_MASTERS = "zookeeper.dolphinscheduler.lock.failover.masters";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_MASTERS = "zookeeper.dolphinscheduler.lock.failover.masters";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_MASTERS = "/lock/failover/masters";
/**
* WorkerServer failover directory registered in zookeeper
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS = "zookeeper.dolphinscheduler.lock.failover.workers";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS = "zookeeper.dolphinscheduler.lock.failover.workers";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS = "/lock/failover/workers";
/**
* MasterServer startup failover runing and fault tolerance process
*/
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS = "zookeeper.dolphinscheduler.lock.failover.startup.masters";
//public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS = "zookeeper.dolphinscheduler.lock.failover.startup.masters";
public static final String ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS = "/lock/failover/startup-masters";
/**
* need send warn times when master server or worker server failover

2
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/CommandType.java

@ -49,7 +49,7 @@ public enum CommandType {
REPEAT_RUNNING(7, "repeat running a process"),
PAUSE(8, "pause a process"),
STOP(9, "stop a process"),
RECOVER_WAITTING_THREAD(10, "recover waitting thread");
RECOVER_WAITTING_THREAD(10, "recover waiting thread");
CommandType(int code, String descp){
this.code = code;

2
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/ExecutionStatus.java

@ -21,7 +21,7 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
/**
* runing status for workflow and task nodes
* running status for workflow and task nodes
*
*/
@Getter

2
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/TaskRecordStatus.java

@ -25,7 +25,7 @@ public enum TaskRecordStatus {
/**
* status
* 0 sucess
* 0 success
* 1 failure
* 2 exception
*/

2
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/model/Server.java

@ -40,7 +40,7 @@ public class Server {
private int port;
/**
* master direcotry in zookeeper
* master directory in zookeeper
*/
private String zkDirectory;

47
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/queue/TaskQueueZkImpl.java

@ -26,27 +26,44 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.utils.Bytes;
import org.apache.dolphinscheduler.common.utils.IpUtils;
import org.apache.dolphinscheduler.common.utils.OSUtils;
import org.apache.dolphinscheduler.common.zk.AbstractZKClient;
import org.apache.curator.framework.CuratorFramework;
import org.apache.dolphinscheduler.common.zk.DefaultEnsembleProvider;
import org.apache.dolphinscheduler.common.zk.ZookeeperConfig;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.dolphinscheduler.common.utils.Preconditions.checkNotNull;
/**
* A singleton of a task queue implemented with zookeeper
* tasks queue implemention
*/
public class TaskQueueZkImpl extends AbstractZKClient implements ITaskQueue {
public class TaskQueueZkImpl implements ITaskQueue {
private static final Logger logger = LoggerFactory.getLogger(TaskQueueZkImpl.class);
private static volatile TaskQueueZkImpl instance;
private CuratorFramework zkClient;
private ZookeeperConfig zookeeperConfig;
private CuratorFramework getZkClient() {
return zkClient;
}
private TaskQueueZkImpl(){
init();
}
@ -376,6 +393,7 @@ public class TaskQueueZkImpl extends AbstractZKClient implements ITaskQueue {
* Init the task queue of zookeeper node
*/
private void init(){
initZkClient();
try {
String tasksQueuePath = getTasksPath(Constants.DOLPHINSCHEDULER_TASKS_QUEUE);
String tasksCancelPath = getTasksPath(Constants.DOLPHINSCHEDULER_TASKS_KILL);
@ -394,6 +412,31 @@ public class TaskQueueZkImpl extends AbstractZKClient implements ITaskQueue {
}
}
private void initZkClient() {
Configuration conf = null;
try {
conf = new PropertiesConfiguration(Constants.ZOOKEEPER_PROPERTIES_PATH);
} catch (ConfigurationException ex) {
logger.error("load zookeeper properties file failed, system exit");
System.exit(-1);
}
zookeeperConfig = ZookeeperConfig.getFromConf(conf);
zkClient = CuratorFrameworkFactory.builder().ensembleProvider(new DefaultEnsembleProvider(checkNotNull(zookeeperConfig.getServerList(), "zookeeper quorum can't be null")))
.retryPolicy(new ExponentialBackoffRetry(zookeeperConfig.getBaseSleepTimeMs(), zookeeperConfig.getMaxRetries(), zookeeperConfig.getMaxSleepMs()))
.sessionTimeoutMs(zookeeperConfig.getSessionTimeoutMs())
.connectionTimeoutMs(zookeeperConfig.getConnectionTimeoutMs())
.build();
zkClient.start();
try {
zkClient.blockUntilConnected();
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Clear the task queue of zookeeper node
@ -429,7 +472,7 @@ public class TaskQueueZkImpl extends AbstractZKClient implements ITaskQueue {
* @return
*/
public String getTasksPath(String key){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_ROOT) + Constants.SINGLE_SLASH + key;
return zookeeperConfig.getDsRoot() + Constants.SINGLE_SLASH + key;
}

39
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/FileUtils.java

@ -152,7 +152,7 @@ public class FileUtils {
}
bufferedReader = new BufferedReader(new StringReader(content));
bufferedWriter = new BufferedWriter(new FileWriter(distFile));
char buf[] = new char[1024];
char[] buf = new char[1024];
int len;
while ((len = bufferedReader.read(buf)) != -1) {
bufferedWriter.write(buf, 0, len);
@ -320,7 +320,7 @@ public class FileUtils {
if (file.isDirectory()) {
throw new IOException("File '" + file + "' exists but is a directory");
}
if (file.canWrite() == false) {
if (!file.canWrite()) {
throw new IOException("File '" + file + "' cannot be written to");
}
} else {
@ -377,41 +377,24 @@ public class FileUtils {
throw new RuntimeException("parentDir not exist, or is not a directory:"+parentDir);
}
File[] schemaDirs = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) {
return true;
}
else {
return false;
}
}
});
return schemaDirs;
return file.listFiles(File::isDirectory);
}
/**
* Get Content
* @param inputStream input stream
* @return string of input stream
* @throws IOException errors
*/
public static String readFile2Str(InputStream inputStream) throws IOException{
String all_content=null;
public static String readFile2Str(InputStream inputStream) {
try {
all_content = new String();
InputStream ins = inputStream;
ByteArrayOutputStream outputstream = new ByteArrayOutputStream();
byte[] str_b = new byte[1024];
int i = -1;
while ((i=ins.read(str_b)) > 0) {
outputstream.write(str_b,0,i);
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length= inputStream.read(buffer)) != -1) {
output.write(buffer,0,length);
}
all_content = outputstream.toString();
return all_content;
return output.toString();
} catch (Exception e) {
logger.error(e.getMessage(),e);
throw new RuntimeException(e);

288
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/Preconditions.java

@ -0,0 +1,288 @@
/*
* 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.common.utils;
import org.springframework.lang.Nullable;
/**
* A collection of static utility methods to validate input.
*
* <p>This class is modelled after Google Guava's Preconditions class, and partly takes code
* from that class. We add this code to here base in order to reduce external
* dependencies.
*/
public final class Preconditions {
// ------------------------------------------------------------------------
// Null checks
// ------------------------------------------------------------------------
/**
* Ensures that the given object reference is not null.
* Upon violation, a {@code NullPointerException} with no message is thrown.
*
* @param reference The object reference
* @return The object reference itself (generically typed).
*
* @throws NullPointerException Thrown, if the passed reference was null.
*/
public static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
/**
* Ensures that the given object reference is not null.
* Upon violation, a {@code NullPointerException} with the given message is thrown.
*
* @param reference The object reference
* @param errorMessage The message for the {@code NullPointerException} that is thrown if the check fails.
* @return The object reference itself (generically typed).
*
* @throws NullPointerException Thrown, if the passed reference was null.
*/
public static <T> T checkNotNull(T reference, @Nullable String errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
}
return reference;
}
/**
* Ensures that the given object reference is not null.
* Upon violation, a {@code NullPointerException} with the given message is thrown.
*
* <p>The error message is constructed from a template and an arguments array, after
* a similar fashion as {@link String#format(String, Object...)}, but supporting only
* {@code %s} as a placeholder.
*
* @param reference The object reference
* @param errorMessageTemplate The message template for the {@code NullPointerException}
* that is thrown if the check fails. The template substitutes its
* {@code %s} placeholders with the error message arguments.
* @param errorMessageArgs The arguments for the error message, to be inserted into the
* message template for the {@code %s} placeholders.
*
* @return The object reference itself (generically typed).
*
* @throws NullPointerException Thrown, if the passed reference was null.
*/
public static <T> T checkNotNull(T reference,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (reference == null) {
throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
}
return reference;
}
// ------------------------------------------------------------------------
// Boolean Condition Checking (Argument)
// ------------------------------------------------------------------------
/**
* Checks the given boolean condition, and throws an {@code IllegalArgumentException} if
* the condition is not met (evaluates to {@code false}).
*
* @param condition The condition to check
*
* @throws IllegalArgumentException Thrown, if the condition is violated.
*/
public static void checkArgument(boolean condition) {
if (!condition) {
throw new IllegalArgumentException();
}
}
/**
* Checks the given boolean condition, and throws an {@code IllegalArgumentException} if
* the condition is not met (evaluates to {@code false}). The exception will have the
* given error message.
*
* @param condition The condition to check
* @param errorMessage The message for the {@code IllegalArgumentException} that is thrown if the check fails.
*
* @throws IllegalArgumentException Thrown, if the condition is violated.
*/
public static void checkArgument(boolean condition, @Nullable Object errorMessage) {
if (!condition) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
}
/**
* Checks the given boolean condition, and throws an {@code IllegalArgumentException} if
* the condition is not met (evaluates to {@code false}).
*
* @param condition The condition to check
* @param errorMessageTemplate The message template for the {@code IllegalArgumentException}
* that is thrown if the check fails. The template substitutes its
* {@code %s} placeholders with the error message arguments.
* @param errorMessageArgs The arguments for the error message, to be inserted into the
* message template for the {@code %s} placeholders.
*
* @throws IllegalArgumentException Thrown, if the condition is violated.
*/
public static void checkArgument(boolean condition,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (!condition) {
throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
}
}
// ------------------------------------------------------------------------
// Boolean Condition Checking (State)
// ------------------------------------------------------------------------
/**
* Checks the given boolean condition, and throws an {@code IllegalStateException} if
* the condition is not met (evaluates to {@code false}).
*
* @param condition The condition to check
*
* @throws IllegalStateException Thrown, if the condition is violated.
*/
public static void checkState(boolean condition) {
if (!condition) {
throw new IllegalStateException();
}
}
/**
* Checks the given boolean condition, and throws an {@code IllegalStateException} if
* the condition is not met (evaluates to {@code false}). The exception will have the
* given error message.
*
* @param condition The condition to check
* @param errorMessage The message for the {@code IllegalStateException} that is thrown if the check fails.
*
* @throws IllegalStateException Thrown, if the condition is violated.
*/
public static void checkState(boolean condition, @Nullable Object errorMessage) {
if (!condition) {
throw new IllegalStateException(String.valueOf(errorMessage));
}
}
/**
* Checks the given boolean condition, and throws an {@code IllegalStateException} if
* the condition is not met (evaluates to {@code false}).
*
* @param condition The condition to check
* @param errorMessageTemplate The message template for the {@code IllegalStateException}
* that is thrown if the check fails. The template substitutes its
* {@code %s} placeholders with the error message arguments.
* @param errorMessageArgs The arguments for the error message, to be inserted into the
* message template for the {@code %s} placeholders.
*
* @throws IllegalStateException Thrown, if the condition is violated.
*/
public static void checkState(boolean condition,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (!condition) {
throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs));
}
}
/**
* Ensures that the given index is valid for an array, list or string of the given size.
*
* @param index index to check
* @param size size of the array, list or string
*
* @throws IllegalArgumentException Thrown, if size is negative.
* @throws IndexOutOfBoundsException Thrown, if the index negative or greater than or equal to size
*/
public static void checkElementIndex(int index, int size) {
checkArgument(size >= 0, "Size was negative.");
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
/**
* Ensures that the given index is valid for an array, list or string of the given size.
*
* @param index index to check
* @param size size of the array, list or string
* @param errorMessage The message for the {@code IndexOutOfBoundsException} that is thrown if the check fails.
*
* @throws IllegalArgumentException Thrown, if size is negative.
* @throws IndexOutOfBoundsException Thrown, if the index negative or greater than or equal to size
*/
public static void checkElementIndex(int index, int size, @Nullable String errorMessage) {
checkArgument(size >= 0, "Size was negative.");
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException(String.valueOf(errorMessage) + " Index: " + index + ", Size: " + size);
}
}
// ------------------------------------------------------------------------
// Utilities
// ------------------------------------------------------------------------
/**
* A simplified formatting method. Similar to {@link String#format(String, Object...)}, but
* with lower overhead (only String parameters, no locale, no format validation).
*
* <p>This method is taken quasi verbatim from the Guava Preconditions class.
*/
private static String format(@Nullable String template, @Nullable Object... args) {
final int numArgs = args == null ? 0 : args.length;
template = String.valueOf(template); // null -> "null"
// start substituting the arguments into the '%s' placeholders
StringBuilder builder = new StringBuilder(template.length() + 16 * numArgs);
int templateStart = 0;
int i = 0;
while (i < numArgs) {
int placeholderStart = template.indexOf("%s", templateStart);
if (placeholderStart == -1) {
break;
}
builder.append(template.substring(templateStart, placeholderStart));
builder.append(args[i++]);
templateStart = placeholderStart + 2;
}
builder.append(template.substring(templateStart));
// if we run out of placeholders, append the extra args in square braces
if (i < numArgs) {
builder.append(" [");
builder.append(args[i++]);
while (i < numArgs) {
builder.append(", ");
builder.append(args[i++]);
}
builder.append(']');
}
return builder.toString();
}
// ------------------------------------------------------------------------
/** Private constructor to prevent instantiation. */
private Preconditions() {}
}

35
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/AbstractListener.java

@ -0,0 +1,35 @@
/*
* 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.common.zk;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
public abstract class AbstractListener implements TreeCacheListener {
@Override
public final void childEvent(final CuratorFramework client, final TreeCacheEvent event) throws Exception {
String path = null == event.getData() ? "" : event.getData().getPath();
if (path.isEmpty()) {
return;
}
dataChanged(client, event, path);
}
protected abstract void dataChanged(final CuratorFramework client, final TreeCacheEvent event, final String path);
}

121
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/AbstractZKClient.java

@ -47,98 +47,15 @@ import static org.apache.dolphinscheduler.common.Constants.*;
/**
* abstract zookeeper client
*/
public abstract class AbstractZKClient {
public abstract class AbstractZKClient extends ZookeeperCachedOperator{
private static final Logger logger = LoggerFactory.getLogger(AbstractZKClient.class);
/**
* load configuration file
*/
protected static Configuration conf;
protected CuratorFramework zkClient = null;
/**
* server stop or not
*/
protected IStoppable stoppable = null;
static {
try {
conf = new PropertiesConfiguration(Constants.ZOOKEEPER_PROPERTIES_PATH);
}catch (ConfigurationException e){
logger.error("load configuration failed : " + e.getMessage(),e);
System.exit(1);
}
}
public AbstractZKClient() {
// retry strategy
RetryPolicy retryPolicy = new ExponentialBackoffRetry(
conf.getInt(Constants.ZOOKEEPER_RETRY_SLEEP),
conf.getInt(Constants.ZOOKEEPER_RETRY_MAXTIME));
try{
// crate zookeeper client
zkClient = CuratorFrameworkFactory.builder()
.connectString(getZookeeperQuorum())
.retryPolicy(retryPolicy)
.sessionTimeoutMs(1000 * conf.getInt(Constants.ZOOKEEPER_SESSION_TIMEOUT))
.connectionTimeoutMs(1000 * conf.getInt(Constants.ZOOKEEPER_CONNECTION_TIMEOUT))
.build();
zkClient.start();
initStateLister();
}catch(Exception e){
logger.error("create zookeeper connect failed : " + e.getMessage(),e);
System.exit(-1);
}
}
/**
*
* register status monitoring events for zookeeper clients
*/
public void initStateLister(){
if(zkClient == null) {
return;
}
// add ConnectionStateListener monitoring zookeeper connection state
ConnectionStateListener csLister = new ConnectionStateListener() {
@Override
public void stateChanged(CuratorFramework client, ConnectionState newState) {
logger.info("state changed , current state : " + newState.name());
/**
* probably session expired
*/
if(newState == ConnectionState.LOST){
// if lost , then exit
logger.info("current zookeepr connection state : connection lost ");
}
}
};
zkClient.getConnectionStateListenable().addListener(csLister);
}
public void start() {
zkClient.start();
logger.info("zookeeper start ...");
}
public void close() {
zkClient.getZookeeperClient().close();
zkClient.close();
logger.info("zookeeper close ...");
}
/**
* heartbeat for zookeeper
* @param znode zookeeper node
@ -328,18 +245,8 @@ public abstract class AbstractZKClient {
*
* @return zookeeper quorum
*/
public static String getZookeeperQuorum(){
StringBuilder sb = new StringBuilder();
String[] zookeeperParamslist = conf.getStringArray(Constants.ZOOKEEPER_QUORUM);
for (String param : zookeeperParamslist) {
sb.append(param).append(Constants.COMMA);
}
if(sb.length() > 0){
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
public String getZookeeperQuorum(){
return getZookeeperConfig().getServerList();
}
/**
@ -420,7 +327,7 @@ public abstract class AbstractZKClient {
* @return get worker node parent path
*/
protected String getWorkerZNodeParentPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_WORKERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_WORKERS;
}
/**
@ -428,7 +335,7 @@ public abstract class AbstractZKClient {
* @return get master node parent path
*/
protected String getMasterZNodeParentPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_MASTERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_MASTERS;
}
/**
@ -436,7 +343,15 @@ public abstract class AbstractZKClient {
* @return get master lock path
*/
public String getMasterLockPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_MASTERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_MASTERS;
}
/**
*
* @return get master lock path
*/
public String getWorkerLockPath(){
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_WORKERS;
}
/**
@ -464,7 +379,7 @@ public abstract class AbstractZKClient {
* @return get dead server node parent path
*/
protected String getDeadZNodeParentPath(){
return conf.getString(ZOOKEEPER_DOLPHINSCHEDULER_DEAD_SERVERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_DEAD_SERVERS;
}
/**
@ -472,7 +387,7 @@ public abstract class AbstractZKClient {
* @return get master start up lock path
*/
public String getMasterStartUpLockPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS;
}
/**
@ -480,7 +395,7 @@ public abstract class AbstractZKClient {
* @return get master failover lock path
*/
public String getMasterFailoverLockPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_MASTERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_MASTERS;
}
/**
@ -488,7 +403,7 @@ public abstract class AbstractZKClient {
* @return get worker failover lock path
*/
public String getWorkerFailoverLockPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS);
return getZookeeperConfig().getDsRoot() + Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_FAILOVER_WORKERS;
}
/**

48
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/DefaultEnsembleProvider.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.common.zk;
import org.apache.curator.ensemble.EnsembleProvider;
import java.io.IOException;
/**
* default conf provider
*/
public class DefaultEnsembleProvider implements EnsembleProvider {
private final String serverList;
public DefaultEnsembleProvider(String serverList){
this.serverList = serverList;
}
@Override
public void start() throws Exception {
//NOP
}
@Override
public String getConnectionString() {
return serverList;
}
@Override
public void close() throws IOException {
//NOP
}
}

82
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperCachedOperator.java

@ -0,0 +1,82 @@
/*
* 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.common.zk;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentHashMap;
import static org.apache.dolphinscheduler.common.utils.Preconditions.*;
import static org.apache.dolphinscheduler.common.utils.Preconditions.checkNotNull;
@Component
public class ZookeeperCachedOperator extends ZookeeperOperator {
private final Logger logger = LoggerFactory.getLogger(ZookeeperCachedOperator.class);
//kay is zk path, value is TreeCache
private ConcurrentHashMap<String, TreeCache> allCaches = new ConcurrentHashMap<>();
/**
* @param cachePath zk path
* @param listener operator
*/
public void registerListener(final String cachePath, final TreeCacheListener listener) {
TreeCache newCache = new TreeCache(zkClient, cachePath);
logger.info("add listener to zk path: {}", cachePath);
try {
newCache.start();
} catch (Exception e) {
logger.error("add listener to zk path: {} failed", cachePath);
throw new RuntimeException(e);
}
newCache.getListenable().addListener(listener);
allCaches.put(cachePath, newCache);
}
public String getFromCache(final String cachePath, final String key) {
ChildData resultInCache = allCaches.get(checkNotNull(cachePath)).getCurrentData(key);
if (null != resultInCache) {
return null == resultInCache.getData() ? null : new String(resultInCache.getData(), StandardCharsets.UTF_8);
}
return null;
}
public TreeCache getTreeCache(final String cachePath) {
return allCaches.get(checkNotNull(cachePath));
}
public void close() {
allCaches.forEach((path, cache) -> {
cache.close();
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
}
});
super.close();
}
}

71
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperConfig.java

@ -0,0 +1,71 @@
/*
* 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.common.zk;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.configuration.Configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* zookeeper conf
*/
@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@PropertySource("classpath:zookeeper.properties")
public class ZookeeperConfig {
//zk connect config
@Value("${zookeeper.quorum}")
private String serverList;
@Value("${zookeeper.retry.base.sleep:100}")
private int baseSleepTimeMs;
@Value("${zookeeper.retry.max.sleep:30000}")
private int maxSleepMs;
@Value("${zookeeper.retry.maxtime:10}")
private int maxRetries;
@Value("${zookeeper.session.timeout:60000}")
private int sessionTimeoutMs;
@Value("${zookeeper.connection.timeout:30000}")
private int connectionTimeoutMs;
@Value("${zookeeper.connection.digest: }")
private String digest;
//ds scheduler install config
@Value("${zookeeper.dolphinscheduler.root:/dolphinscheduler}")
private String dsRoot;
public static ZookeeperConfig getFromConf(Configuration conf){
return ZookeeperConfig.builder().serverList(conf.getString("zookeeper.quorum")).baseSleepTimeMs(conf.getInt("zookeeper.retry.base.sleep"))
.maxSleepMs(conf.getInt("zookeeper.retry.max.sleep")).maxRetries(conf.getInt("zookeeper.retry.maxtime"))
.sessionTimeoutMs(conf.getInt("zookeeper.session.timeout")).connectionTimeoutMs(conf.getInt("zookeeper.connection.timeout"))
.dsRoot(conf.getString("zookeeper.dolphinscheduler.root")).build();
}
}

232
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/zk/ZookeeperOperator.java

@ -0,0 +1,232 @@
/*
* 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.common.zk;
import org.apache.commons.lang.StringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.ACLProvider;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.apache.dolphinscheduler.common.utils.Preconditions.*;
import static org.apache.dolphinscheduler.common.utils.Preconditions.checkNotNull;
/**
* zk base operator
*/
@Component
public class ZookeeperOperator implements InitializingBean {
private final Logger logger = LoggerFactory.getLogger(ZookeeperOperator.class);
@Autowired
private ZookeeperConfig zookeeperConfig;
protected CuratorFramework zkClient;
@Override
public void afterPropertiesSet() throws Exception {
this.zkClient = buildClient();
initStateLister();
//init();
}
//for subclass
//protected void init(){}
public void initStateLister() {
checkNotNull(zkClient);
zkClient.getConnectionStateListenable().addListener((client, newState) -> {
if(newState == ConnectionState.LOST){
logger.error("connection lost from zookeeper");
} else if(newState == ConnectionState.RECONNECTED){
logger.info("reconnected to zookeeper");
} else if(newState == ConnectionState.SUSPENDED){
logger.warn("connection SUSPENDED to zookeeper");
}
});
}
private CuratorFramework buildClient() {
logger.info("zookeeper registry center init, server lists is: {}.", zookeeperConfig.getServerList());
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder().ensembleProvider(new DefaultEnsembleProvider(checkNotNull(zookeeperConfig.getServerList(),"zookeeper quorum can't be null")))
.retryPolicy(new ExponentialBackoffRetry(zookeeperConfig.getBaseSleepTimeMs(), zookeeperConfig.getMaxRetries(), zookeeperConfig.getMaxSleepMs()));
//these has default value
if (0 != zookeeperConfig.getSessionTimeoutMs()) {
builder.sessionTimeoutMs(zookeeperConfig.getSessionTimeoutMs());
}
if (0 != zookeeperConfig.getConnectionTimeoutMs()) {
builder.connectionTimeoutMs(zookeeperConfig.getConnectionTimeoutMs());
}
if (StringUtils.isNotBlank(zookeeperConfig.getDigest())) {
builder.authorization("digest", zookeeperConfig.getDigest().getBytes(StandardCharsets.UTF_8)).aclProvider(new ACLProvider() {
@Override
public List<ACL> getDefaultAcl() {
return ZooDefs.Ids.CREATOR_ALL_ACL;
}
@Override
public List<ACL> getAclForPath(final String path) {
return ZooDefs.Ids.CREATOR_ALL_ACL;
}
});
}
zkClient = builder.build();
zkClient.start();
try {
zkClient.blockUntilConnected();
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
return zkClient;
}
public String get(final String key) {
try {
return new String(zkClient.getData().forPath(key), StandardCharsets.UTF_8);
} catch (Exception ex) {
logger.error("get key : {}", key, ex);
}
return null;
}
public List<String> getChildrenKeys(final String key) {
List<String> values;
try {
values = zkClient.getChildren().forPath(key);
if (CollectionUtils.isEmpty(values)) {
logger.warn("getChildrenKeys key : {} is empty", key);
}
return values;
} catch (InterruptedException ex) {
logger.error("getChildrenKeys key : {} InterruptedException", key);
throw new IllegalStateException(ex);
} catch (Exception ex) {
logger.error("getChildrenKeys key : {}", key, ex);
throw new RuntimeException(ex);
}
}
public boolean isExisted(final String key) {
try {
return zkClient.checkExists().forPath(key) != null;
} catch (Exception ex) {
logger.error("isExisted key : {}", key, ex);
}
return false;
}
public void persist(final String key, final String value) {
try {
if (!isExisted(key)) {
zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(key, value.getBytes(StandardCharsets.UTF_8));
} else {
update(key, value);
}
} catch (Exception ex) {
logger.error("persist key : {} , value : {}", key, value, ex);
}
}
public void update(final String key, final String value) {
try {
zkClient.inTransaction().check().forPath(key).and().setData().forPath(key, value.getBytes(StandardCharsets.UTF_8)).and().commit();
} catch (Exception ex) {
logger.error("update key : {} , value : {}", key, value, ex);
}
}
public void persistEphemeral(final String key, final String value) {
try {
if (isExisted(key)) {
try {
zkClient.delete().deletingChildrenIfNeeded().forPath(key);
} catch (KeeperException.NoNodeException ignore) {
//NOP
}
}
zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(key, value.getBytes(StandardCharsets.UTF_8));
} catch (final Exception ex) {
logger.error("persistEphemeral key : {} , value : {}", key, value, ex);
}
}
public void persistEphemeral(String key, String value, boolean overwrite) {
try {
if (overwrite) {
persistEphemeral(key, value);
} else {
if (!isExisted(key)) {
zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(key, value.getBytes(StandardCharsets.UTF_8));
}
}
} catch (final Exception ex) {
logger.error("persistEphemeral key : {} , value : {}, overwrite : {}", key, value, overwrite, ex);
}
}
public void persistEphemeralSequential(final String key, String value) {
try {
zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(key, value.getBytes(StandardCharsets.UTF_8));
} catch (final Exception ex) {
logger.error("persistEphemeralSequential key : {}", key, ex);
}
}
public void remove(final String key) {
try {
if (isExisted(key)) {
zkClient.delete().deletingChildrenIfNeeded().forPath(key);
}
} catch (KeeperException.NoNodeException ignore) {
//NOP
} catch (final Exception ex) {
logger.error("remove key : {}", key, ex);
}
}
public CuratorFramework getZkClient() {
return zkClient;
}
public ZookeeperConfig getZookeeperConfig() {
return zookeeperConfig;
}
public void close() {
CloseableUtils.closeQuietly(zkClient);
}
}

19
dolphinscheduler-common/src/main/resources/zookeeper.properties

@ -22,21 +22,22 @@ zookeeper.quorum=localhost:2181
zookeeper.dolphinscheduler.root=/dolphinscheduler
#zookeeper server dirctory
zookeeper.dolphinscheduler.dead.servers=/dolphinscheduler/dead-servers
zookeeper.dolphinscheduler.masters=/dolphinscheduler/masters
zookeeper.dolphinscheduler.workers=/dolphinscheduler/workers
#zookeeper.dolphinscheduler.dead.servers=/dolphinscheduler/dead-servers
#zookeeper.dolphinscheduler.masters=/dolphinscheduler/masters
#zookeeper.dolphinscheduler.workers=/dolphinscheduler/workers
#zookeeper lock dirctory
zookeeper.dolphinscheduler.lock.masters=/dolphinscheduler/lock/masters
zookeeper.dolphinscheduler.lock.workers=/dolphinscheduler/lock/workers
#zookeeper.dolphinscheduler.lock.masters=/dolphinscheduler/lock/masters
#zookeeper.dolphinscheduler.lock.workers=/dolphinscheduler/lock/workers
#dolphinscheduler failover directory
zookeeper.dolphinscheduler.lock.failover.masters=/dolphinscheduler/lock/failover/masters
zookeeper.dolphinscheduler.lock.failover.workers=/dolphinscheduler/lock/failover/workers
zookeeper.dolphinscheduler.lock.failover.startup.masters=/dolphinscheduler/lock/failover/startup-masters
#zookeeper.dolphinscheduler.lock.failover.masters=/dolphinscheduler/lock/failover/masters
#zookeeper.dolphinscheduler.lock.failover.workers=/dolphinscheduler/lock/failover/workers
#zookeeper.dolphinscheduler.lock.failover.startup.masters=/dolphinscheduler/lock/failover/startup-masters
#dolphinscheduler failover directory
zookeeper.session.timeout=300
zookeeper.connection.timeout=300
zookeeper.retry.sleep=1000
zookeeper.retry.base.sleep=100
zookeeper.retry.max.sleep=30000
zookeeper.retry.maxtime=5

16
dolphinscheduler-dist/release-docs/LICENSE vendored

@ -505,21 +505,23 @@ The text of each license is also included at licenses/ui-licenses/LICENSE-[proje
========================================
MIT licenses
========================================
vue 2.5.17: https://github.com/vuejs/vue MIT
jquery 1.12.4: https://github.com/jquery/jquery MIT
vue-router 2.7.0: https://github.com/vuejs/vue-router MIT
vuex 3.0.0: https://github.com/vuejs/vuex MIT
ans-UI 1.1.7: https://github.com/analysys/ans-ui MIT
axios 0.16.2: https://github.com/axios/axios MIT
bootstrap 3.3.7: https://github.com/twbs/bootstrap MIT
canvg 1.5.1: https://github.com/canvg/canvg MIT
clipboard 2.0.1: https://github.com/zenorocha/clipboard.js MIT
codemirror 5.43.0: https://github.com/codemirror/CodeMirror MIT
dayjs 1.7.8: https://github.com/iamkun/dayjs MIT
html2canvas 0.5.0-beta4: https://github.com/niklasvh/html2canvas MIT
jquery 3.3.1: https://github.com/jquery/jquery MIT
jquery-ui 1.12.1: https://github.com/jquery/jquery-ui MIT
js-cookie 2.2.1: https://github.com/js-cookie/js-cookie MIT
jsplumb 2.8.6: https://github.com/jsplumb/jsplumb MIT and GPLv2
lodash 4.17.11: https://github.com/lodash/lodash MIT
vue 2.5.17: https://github.com/vuejs/vue MIT
vue-router 2.7.0: https://github.com/vuejs/vue-router MIT
vuex 3.0.0: https://github.com/vuejs/vuex MIT
vuex-router-sync 4.1.2: https://github.com/vuejs/vuex-router-sync MIT
ans-UI 0.0.22: https://github.com/analysys/ans-ui MIT
axios 0.16.2: https://github.com/axios/axios MIT
jsplumb 2.8.6: https://github.com/jsplumb/jsplumb MIT and GPLv2
========================================
Apache 2.0 licenses

45
dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-jquery-ui vendored

@ -0,0 +1,45 @@
MIT License
Copyright jQuery Foundation and other contributors, https://jquery.org/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery-ui
The following license applies to all parts of this software except as
documented below:
====
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.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code contained within the demos directory.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from
the terms above.

21
dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-js-cookie vendored

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors
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.

9
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java

@ -35,6 +35,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import javax.annotation.PostConstruct;
@ -56,6 +58,7 @@ public class MasterServer implements IStoppable {
/**
* zk master client
*/
@Autowired
private ZKMasterClient zkMasterClient = null;
/**
@ -95,8 +98,7 @@ public class MasterServer implements IStoppable {
* @param args arguments
*/
public static void main(String[] args) {
SpringApplication.run(MasterServer.class, args);
new SpringApplicationBuilder(MasterServer.class).web(WebApplicationType.NONE).run(args);
}
/**
@ -104,11 +106,10 @@ public class MasterServer implements IStoppable {
*/
@PostConstruct
public void run(){
zkMasterClient.init();
masterSchedulerService = ThreadUtils.newDaemonSingleThreadExecutor("Master-Scheduler-Thread");
zkMasterClient = ZKMasterClient.getZKMasterClient(processDao);
heartbeatMasterService = ThreadUtils.newDaemonThreadScheduledExecutor("Master-Main-Thread",Constants.defaulMasterHeartbeatThreadNum);
// heartbeat thread implement

71
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/utils/SparkArgsUtils.java

@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.server.utils;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ProgramType;
import org.apache.dolphinscheduler.common.process.ResourceInfo;
import org.apache.dolphinscheduler.common.task.spark.SparkParameters;
import org.apache.commons.lang.StringUtils;
@ -53,63 +54,69 @@ public class SparkArgsUtils {
args.add(param.getDeployMode());
if(param.getProgramType() !=null ){
if(param.getProgramType()!=ProgramType.PYTHON){
if (StringUtils.isNotEmpty(param.getMainClass())) {
args.add(Constants.MAIN_CLASS);
args.add(param.getMainClass());
}
}
ProgramType type = param.getProgramType();
String mainClass = param.getMainClass();
if(type != null && type != ProgramType.PYTHON && StringUtils.isNotEmpty(mainClass)){
args.add(Constants.MAIN_CLASS);
args.add(mainClass);
}
if (param.getDriverCores() != 0) {
int driverCores = param.getDriverCores();
if (driverCores != 0) {
args.add(Constants.DRIVER_CORES);
args.add(String.format("%d", param.getDriverCores()));
args.add(String.format("%d", driverCores));
}
if (StringUtils.isNotEmpty(param.getDriverMemory())) {
String driverMemory = param.getDriverMemory();
if (StringUtils.isNotEmpty(driverMemory)) {
args.add(Constants.DRIVER_MEMORY);
args.add(param.getDriverMemory());
args.add(driverMemory);
}
if (param.getNumExecutors() != 0) {
int numExecutors = param.getNumExecutors();
if (numExecutors != 0) {
args.add(Constants.NUM_EXECUTORS);
args.add(String.format("%d", param.getNumExecutors()));
args.add(String.format("%d", numExecutors));
}
if (param.getExecutorCores() != 0) {
int executorCores = param.getExecutorCores();
if (executorCores != 0) {
args.add(Constants.EXECUTOR_CORES);
args.add(String.format("%d", param.getExecutorCores()));
args.add(String.format("%d", executorCores));
}
if (StringUtils.isNotEmpty(param.getExecutorMemory())) {
String executorMemory = param.getExecutorMemory();
if (StringUtils.isNotEmpty(executorMemory)) {
args.add(Constants.EXECUTOR_MEMORY);
args.add(param.getExecutorMemory());
args.add(executorMemory);
}
// --files --conf --libjar ...
if (StringUtils.isNotEmpty(param.getOthers())) {
String others = param.getOthers();
if(!others.contains("--queue")){
if (StringUtils.isNotEmpty(param.getQueue())) {
args.add(Constants.SPARK_QUEUE);
args.add(param.getQueue());
}
String others = param.getOthers();
String queue = param.getQueue();
if (StringUtils.isNotEmpty(others)) {
if(!others.contains(Constants.SPARK_QUEUE) && StringUtils.isNotEmpty(queue)){
args.add(Constants.SPARK_QUEUE);
args.add(queue);
}
args.add(param.getOthers());
}else if (StringUtils.isNotEmpty(param.getQueue())) {
args.add(others);
}else if (StringUtils.isNotEmpty(queue)) {
args.add(Constants.SPARK_QUEUE);
args.add(param.getQueue());
args.add(queue);
}
if (param.getMainJar() != null) {
args.add(param.getMainJar().getRes());
ResourceInfo mainJar = param.getMainJar();
if (mainJar != null) {
args.add(mainJar.getRes());
}
if (StringUtils.isNotEmpty(param.getMainArgs())) {
args.add(param.getMainArgs());
String mainArgs = param.getMainArgs();
if (StringUtils.isNotEmpty(mainArgs)) {
args.add(mainArgs);
}
return args;

9
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java

@ -42,7 +42,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import javax.annotation.PostConstruct;
@ -67,6 +68,7 @@ public class WorkerServer implements IStoppable {
/**
* zk worker client
*/
@Autowired
private ZKWorkerClient zkWorkerClient = null;
@ -127,7 +129,7 @@ public class WorkerServer implements IStoppable {
* @param args arguments
*/
public static void main(String[] args) {
SpringApplication.run(WorkerServer.class,args);
new SpringApplicationBuilder(WorkerServer.class).web(WebApplicationType.NONE).run(args);
}
@ -136,8 +138,7 @@ public class WorkerServer implements IStoppable {
*/
@PostConstruct
public void run(){
zkWorkerClient = ZKWorkerClient.getZKWorkerClient();
zkWorkerClient.init();
this.taskQueue = TaskQueueFactory.getTaskQueueInstance();

148
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/zk/ZKMasterClient.java

@ -16,10 +16,12 @@
*/
package org.apache.dolphinscheduler.server.zk;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ExecutionStatus;
import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.dolphinscheduler.common.model.Server;
import org.apache.dolphinscheduler.common.zk.AbstractListener;
import org.apache.dolphinscheduler.common.zk.AbstractZKClient;
import org.apache.dolphinscheduler.dao.AlertDao;
import org.apache.dolphinscheduler.dao.DaoFactory;
@ -36,6 +38,8 @@ import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@ -47,6 +51,7 @@ import java.util.concurrent.ThreadFactory;
*
* single instance
*/
@Component
public class ZKMasterClient extends AbstractZKClient {
/**
@ -71,53 +76,14 @@ public class ZKMasterClient extends AbstractZKClient {
/**
* flow database access
*/
@Autowired
private ProcessDao processDao;
/**
* zkMasterClient
*/
private static ZKMasterClient zkMasterClient = null;
/**
* master path children cache
*/
private PathChildrenCache masterPathChildrenCache;
/**
* worker path children cache
*/
private PathChildrenCache workerPathChildrenCache;
/**
* constructor
*
* @param processDao process dao
*/
private ZKMasterClient(ProcessDao processDao){
this.processDao = processDao;
init();
}
/**
* default constructor
*/
private ZKMasterClient(){}
/**
* get zkMasterClient
*
* @param processDao process dao
* @return ZKMasterClient zookeeper master client
*/
public static synchronized ZKMasterClient getZKMasterClient(ProcessDao processDao){
if(zkMasterClient == null){
zkMasterClient = new ZKMasterClient(processDao);
}
zkMasterClient.processDao = processDao;
return zkMasterClient;
}
/**
* init
*/
@ -157,22 +123,6 @@ public class ZKMasterClient extends AbstractZKClient {
}
}
@Override
public void close(){
try {
if(masterPathChildrenCache != null){
masterPathChildrenCache.close();
}
if(workerPathChildrenCache != null){
workerPathChildrenCache.close();
}
super.close();
} catch (Exception ignore) {
}
}
/**
* init dao
@ -209,41 +159,29 @@ public class ZKMasterClient extends AbstractZKClient {
}
/**
* monitor master
*/
public void listenerMaster(){
masterPathChildrenCache = new PathChildrenCache(zkClient,
getZNodeParentPath(ZKNodeType.MASTER), true ,defaultThreadFactory);
try {
masterPathChildrenCache.start();
masterPathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
switch (event.getType()) {
case CHILD_ADDED:
logger.info("master node added : {}",event.getData().getPath());
break;
case CHILD_REMOVED:
String path = event.getData().getPath();
String serverHost = getHostByEventDataPath(path);
if(checkServerSelfDead(serverHost, ZKNodeType.MASTER)){
return;
}
removeZKNodePath(path, ZKNodeType.MASTER, true);
break;
case CHILD_UPDATED:
break;
default:
break;
}
registerListener(getZNodeParentPath(ZKNodeType.MASTER), new AbstractListener() {
@Override
protected void dataChanged(CuratorFramework client, TreeCacheEvent event, String path) {
switch (event.getType()) {
case NODE_ADDED:
logger.info("master node added : {}", path);
break;
case NODE_REMOVED:
String serverHost = getHostByEventDataPath(path);
if (checkServerSelfDead(serverHost, ZKNodeType.MASTER)) {
return;
}
removeZKNodePath(path, ZKNodeType.MASTER, true);
break;
default:
break;
}
});
}catch (Exception e){
logger.error("monitor master failed : " + e.getMessage(),e);
}
}
});
}
/**
@ -338,30 +276,22 @@ public class ZKMasterClient extends AbstractZKClient {
* monitor worker
*/
public void listenerWorker(){
workerPathChildrenCache = new PathChildrenCache(zkClient,
getZNodeParentPath(ZKNodeType.WORKER),true ,defaultThreadFactory);
try {
workerPathChildrenCache.start();
workerPathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) {
switch (event.getType()) {
case CHILD_ADDED:
logger.info("node added : {}" ,event.getData().getPath());
break;
case CHILD_REMOVED:
String path = event.getData().getPath();
logger.info("node deleted : {}",event.getData().getPath());
removeZKNodePath(path, ZKNodeType.WORKER, true);
break;
default:
break;
}
registerListener(getZNodeParentPath(ZKNodeType.WORKER), new AbstractListener() {
@Override
protected void dataChanged(CuratorFramework client, TreeCacheEvent event, String path) {
switch (event.getType()) {
case NODE_ADDED:
logger.info("worker node added : {}", path);
break;
case NODE_REMOVED:
logger.info("worker node deleted : {}", path);
removeZKNodePath(path, ZKNodeType.WORKER, true);
break;
default:
break;
}
});
}catch (Exception e){
logger.error("listener worker failed : " + e.getMessage(),e);
}
}
});
}

104
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/zk/ZKWorkerClient.java

@ -16,8 +16,10 @@
*/
package org.apache.dolphinscheduler.server.zk;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.dolphinscheduler.common.zk.AbstractListener;
import org.apache.dolphinscheduler.common.zk.AbstractZKClient;
import org.apache.commons.lang.StringUtils;
import org.apache.curator.framework.CuratorFramework;
@ -27,6 +29,7 @@ import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadFactory;
@ -35,6 +38,7 @@ import java.util.concurrent.ThreadFactory;
* zookeeper worker client
* single instance
*/
@Component
public class ZKWorkerClient extends AbstractZKClient {
/**
@ -42,11 +46,6 @@ public class ZKWorkerClient extends AbstractZKClient {
*/
private static final Logger logger = LoggerFactory.getLogger(ZKWorkerClient.class);
/**
* thread factory
*/
private static final ThreadFactory defaultThreadFactory = ThreadUtils.newGenericThreadFactory("Worker-Main-Thread");
/**
* worker znode
@ -54,24 +53,10 @@ public class ZKWorkerClient extends AbstractZKClient {
private String workerZNode = null;
/**
* zookeeper worker client
*/
private static ZKWorkerClient zkWorkerClient = null;
/**
* worker path children cache
*/
private PathChildrenCache workerPathChildrenCache;
private ZKWorkerClient(){
init();
}
/**
* init
*/
private void init(){
public void init(){
// init system znode
this.initSystemZNode();
@ -83,31 +68,6 @@ public class ZKWorkerClient extends AbstractZKClient {
this.registWorker();
}
@Override
public void close(){
try {
if(workerPathChildrenCache != null){
workerPathChildrenCache.close();
}
super.close();
} catch (Exception ignore) {
}
}
/**
* get zookeeper worker client
*
* @return ZKWorkerClient
*/
public static synchronized ZKWorkerClient getZKWorkerClient(){
if(zkWorkerClient == null){
zkWorkerClient = new ZKWorkerClient();
}
return zkWorkerClient;
}
/**
* register worker
*/
@ -128,34 +88,25 @@ public class ZKWorkerClient extends AbstractZKClient {
* monitor worker
*/
private void listenerWorker(){
workerPathChildrenCache = new PathChildrenCache(zkClient, getZNodeParentPath(ZKNodeType.WORKER), true, defaultThreadFactory);
try {
workerPathChildrenCache.start();
workerPathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
switch (event.getType()) {
case CHILD_ADDED:
logger.info("node added : {}" ,event.getData().getPath());
break;
case CHILD_REMOVED:
String path = event.getData().getPath();
//find myself dead
String serverHost = getHostByEventDataPath(path);
if(checkServerSelfDead(serverHost, ZKNodeType.WORKER)){
return;
}
break;
case CHILD_UPDATED:
break;
default:
break;
}
registerListener(getZNodeParentPath(ZKNodeType.WORKER), new AbstractListener() {
@Override
protected void dataChanged(CuratorFramework client, TreeCacheEvent event, String path) {
switch (event.getType()) {
case NODE_ADDED:
logger.info("worker node added : {}", path);
break;
case NODE_REMOVED:
//find myself dead
String serverHost = getHostByEventDataPath(path);
if(checkServerSelfDead(serverHost, ZKNodeType.WORKER)){
return;
}
break;
default:
break;
}
});
}catch (Exception e){
logger.error("monitor worker failed : " + e.getMessage(),e);
}
}
});
}
@ -167,13 +118,4 @@ public class ZKWorkerClient extends AbstractZKClient {
return workerZNode;
}
/**
* get worker lock path
* @return worker lock path
*/
public String getWorkerLockPath(){
return conf.getString(Constants.ZOOKEEPER_DOLPHINSCHEDULER_LOCK_WORKERS);
}
}

5
dolphinscheduler-server/src/main/resources/application-master.properties

@ -15,7 +15,4 @@
# limitations under the License.
#
logging.config=classpath:master_logback.xml
# server port
server.port=5566
logging.config=classpath:master_logback.xml

3
dolphinscheduler-server/src/main/resources/application-worker.properties

@ -16,6 +16,3 @@
#
logging.config=classpath:worker_logback.xml
# server port
server.port=7788

128
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/utils/SparkArgsUtilsTest.java

@ -0,0 +1,128 @@
/*
* 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.server.utils;
import org.apache.dolphinscheduler.common.enums.ProgramType;
import org.apache.dolphinscheduler.common.process.ResourceInfo;
import org.apache.dolphinscheduler.common.task.spark.SparkParameters;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
/**
* Test SparkArgsUtils
*/
public class SparkArgsUtilsTest {
private static final Logger logger = LoggerFactory.getLogger(SparkArgsUtilsTest.class);
public String mode = "cluster";
public String mainClass = "com.test";
public ResourceInfo mainJar = null;
public String mainArgs = "partitions=2";
public String driverMemory = "2G";
public String executorMemory = "4G";
public ProgramType programType = ProgramType.JAVA;
public int driverCores = 2;
public int executorCores = 6;
public String sparkVersion = "SPARK1";
public int numExecutors = 4;
public String queue = "queue1";
@Before
public void setUp() throws Exception {
ResourceInfo main = new ResourceInfo();
main.setRes("testspark-1.0.0-SNAPSHOT.jar");
mainJar = main;
}
/**
* Test buildArgs
*/
@Test
public void testBuildArgs() {
//Define params
SparkParameters param = new SparkParameters();
param.setDeployMode(mode);
param.setMainClass(mainClass);
param.setDriverCores(driverCores);
param.setDriverMemory(driverMemory);
param.setExecutorCores(executorCores);
param.setExecutorMemory(executorMemory);
param.setMainJar(mainJar);
param.setNumExecutors(numExecutors);
param.setProgramType(programType);
param.setSparkVersion(sparkVersion);
param.setMainArgs(mainArgs);
param.setQueue(queue);
//Invoke buildArgs
List<String> result = SparkArgsUtils.buildArgs(param);
for (String s : result) {
logger.info(s);
}
//Expected values and order
assertEquals(result.size(),20);
assertEquals(result.get(0),"--master");
assertEquals(result.get(1),"yarn");
assertEquals(result.get(2),"--deploy-mode");
assertEquals(result.get(3),mode);
assertEquals(result.get(4),"--class");
assertEquals(result.get(5),mainClass);
assertEquals(result.get(6),"--driver-cores");
assertSame(Integer.valueOf(result.get(7)),driverCores);
assertEquals(result.get(8),"--driver-memory");
assertEquals(result.get(9),driverMemory);
assertEquals(result.get(10),"--num-executors");
assertSame(Integer.valueOf(result.get(11)),numExecutors);
assertEquals(result.get(12),"--executor-cores");
assertSame(Integer.valueOf(result.get(13)),executorCores);
assertEquals(result.get(14),"--executor-memory");
assertEquals(result.get(15),executorMemory);
assertEquals(result.get(16),"--queue");
assertEquals(result.get(17),queue);
assertEquals(result.get(18),mainJar.getRes());
assertEquals(result.get(19),mainArgs);
//Others param without --queue
SparkParameters param1 = new SparkParameters();
param1.setOthers("--files xxx/hive-site.xml");
param1.setQueue(queue);
result = SparkArgsUtils.buildArgs(param1);
assertEquals(result.size(),7);
}
}

21
dolphinscheduler-ui/build/config.js

@ -202,28 +202,15 @@ const baseConfig = {
],
alias: {
'@': resolve('src/js'),
'~': resolve('src/lib')
'~': resolve('src/lib'),
'jquery':'jquery/dist/jquery.min.js',
'jquery-ui': 'jquery-ui'
},
extensions: ['.js', 'json', '.vue', '.scss']
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'jquery': '$',
'lodash': '_',
'bootstrap': 'bootstrap',
'd3': 'd3',
'canvg': 'canvg',
'html2canvas': 'html2canvas',
'./jsplumb': 'jsPlumb',
'./highlight.js': 'highlight.js',
'./clipboard': 'clipboard',
'./codemirror': 'CodeMirror'
},
plugins: [
new VueLoaderPlugin(),
new webpack.ProvidePlugin({ vue: 'Vue', _: 'lodash' }),
new webpack.ProvidePlugin({ vue: 'Vue', _: 'lodash',jQuery:"jquery/dist/jquery.min.js",$:"jquery/dist/jquery.min.js" }),
new webpack.DefinePlugin({
PUBLIC_PATH: JSON.stringify(process.env.PUBLIC_PATH ? process.env.PUBLIC_PATH : '')
}),

16
dolphinscheduler-ui/package.json

@ -1,14 +1,14 @@
{
"name": "dolphinscheduler",
"name": "dolphinscheduler-ui-frontend",
"version": "1.0.0",
"description": "dolphinscheduler",
"author": "gongzijian <gongzijian@analysys.com.cn>",
"description": "A vue.js project",
"author": "DolphinScheduler",
"scripts": {
"build": "npm run clean && cross-env NODE_ENV=production webpack --config ./build/webpack.config.prod.js && cp -rf src/3rdcss dist && cp -rf src/3rdjs dist",
"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",
"clean": "rimraf dist",
"start": "npm run dev",
"build:release": "npm run clean && cross-env NODE_ENV=production PUBLIC_PATH=/dolphinscheduler/ui webpack --config ./build/webpack.config.release.js && cp -rf src/3rdcss dist && cp -rf src/3rdjs dist"
"build:release": "npm run clean && cross-env NODE_ENV=production PUBLIC_PATH=/dolphinscheduler/ui webpack --config ./build/webpack.config.release.js"
},
"dependencies": {
"ans-ui": "1.1.7",
@ -19,9 +19,11 @@
"codemirror": "^5.43.0",
"d3": "^3.5.17",
"dayjs": "^1.7.8",
"echarts": "^4.1.0",
"echarts": "4.1.0",
"html2canvas": "^0.5.0-beta4",
"jquery": "1.12.4",
"jquery": "3.3.1",
"jquery-ui": "^1.12.1",
"js-cookie": "^2.2.1",
"jsplumb": "^2.8.6",
"lodash": "^4.17.11",
"vue": "^2.5.17",

4
dolphinscheduler-ui/src/3rdcss/animate.css vendored

File diff suppressed because one or more lines are too long

5
dolphinscheduler-ui/src/3rdcss/bootstrap.min.css vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdcss/codemirror.min.css vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdcss/jsplumbtoolkit-defaults.min.css vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdcss/mdn-like.min.css vendored

@ -1,4 +0,0 @@
/*
* Licensed MIT
*/
.cm-s-mdn-like.CodeMirror{color:#999;background-color:#fff}.cm-s-mdn-like .CodeMirror-line::selection,.cm-s-mdn-like .CodeMirror-line>span::selection,.cm-s-mdn-like .CodeMirror-line>span>span::selection,.cm-s-mdn-like div.CodeMirror-selected{background:#cfc}.cm-s-mdn-like .CodeMirror-line::-moz-selection,.cm-s-mdn-like .CodeMirror-line>span::-moz-selection,.cm-s-mdn-like .CodeMirror-line>span>span::-moz-selection{background:#cfc}.cm-s-mdn-like .CodeMirror-gutters{background:#f8f8f8;color:#333}.cm-s-mdn-like .CodeMirror-linenumber{color:#aaa;padding-left:8px}.cm-s-mdn-like .CodeMirror-cursor{border-left:2px solid #222}.cm-s-mdn-like .cm-keyword{color:#6262FF}.cm-s-mdn-like .cm-atom{color:#F90}.cm-s-mdn-like .cm-number{color:#ca7841}.cm-s-mdn-like .cm-def{color:#8DA6CE}.cm-s-mdn-like span.cm-tag,.cm-s-mdn-like span.cm-variable-2{color:#690}.cm-s-mdn-like .cm-variable,.cm-s-mdn-like span.cm-def,.cm-s-mdn-like span.cm-variable-3{color:#07a}.cm-s-mdn-like .cm-property{color:#905}.cm-s-mdn-like .cm-qualifier{color:#690}.cm-s-mdn-like .cm-operator{color:#cda869}.cm-s-mdn-like .cm-comment{color:#777;font-weight:400}.cm-s-mdn-like .cm-string{color:#07a;font-style:italic}.cm-s-mdn-like .cm-string-2{color:#bd6b18}.cm-s-mdn-like .cm-meta{color:#000}.cm-s-mdn-like .cm-builtin{color:#9B7536}.cm-s-mdn-like .cm-tag{color:#997643}.cm-s-mdn-like .cm-attribute{color:#d6bb6d}.cm-s-mdn-like .cm-header{color:#FF6400}.cm-s-mdn-like .cm-hr{color:#AEAEAE}.cm-s-mdn-like .cm-link{color:#ad9361;font-style:italic;text-decoration:none}.cm-s-mdn-like .cm-error{border-bottom:1px solid red}div.cm-s-mdn-like .CodeMirror-activeline-background{background:#efefff}div.cm-s-mdn-like span.CodeMirror-matchingbracket{outline:grey solid 1px;color:inherit}.cm-s-mdn-like.CodeMirror{background-image:url(/~/codemirror/5.20.0/theme/mdn-like.min.css)}

1
dolphinscheduler-ui/src/3rdcss/normalize.min.css vendored

@ -1 +0,0 @@
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}

2
dolphinscheduler-ui/src/3rdcss/reset.css

@ -1,2 +0,0 @@
/*! reset.css (extends from normalize.css) for Analysys.cn FE Group | MIT License | by @allex_wang
*/article,aside,blockquote,body,button,code,dd,details,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,input,legend,li,menu,nav,ol,p,pre,section,td,textarea,th,ul{margin:0;padding:0}h1,h2,h3,p{font-style:normal}table{border-collapse:collapse;border-spacing:0}button,input,select,textarea{font-family:inherit;font-size:inherit}ol,ul{list-style:none}img{border:0}body{font:13px/1.5 PingFangSC-Light,Helvetica Neue,Helvetica,Microsoft Yahei,Arial,Hiragino Sans GB,tahoma,SimSun,sans-serif;-webkit-backface-visibility:hidden;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input::-ms-clear,input::-ms-reveal{display:none}a,body{color:#333}:focus{outline:0}*,:after,:before{-webkit-box-sizing:border-box;box-sizing:border-box}a:hover{color:#0097e0;text-decoration:none}[hidden],[v-cloak]{display:none}body ::-webkit-scrollbar{width:4px;height:4px}body ::-webkit-scrollbar-track{background:hsla(0,0%,100%,0);border-radius:2x;margin:4px 0}body ::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,0);border-radius:2px;-webkit-transition:background .2s ease-in-out;transition:background .2s ease-in-out}[class*=scrollbar]:hover::-webkit-scrollbar-thumb{background:#70bdf7}.clearfix,.outer{zoom:1}.clearfix:after,.outer:after{clear:both;content:" ";display:block;width:0;height:0;visibility:hidden}.f-show{display:block}.f-hide{display:none}.f-pr{position:relative}.f-fl{float:left}.f-fr{float:right}.float-left{float:left}.float-right{float:right}.f-no-select{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.f-word-break{white-space:normal;word-wrap:break-word;word-break:break-all}.f-text-ellipis{overflow:hidden;word-wrap:normal;white-space:nowrap;text-overflow:ellipsis}.f-link{display:inline-block;text-decoration:none;width:100%;height:100%}.f-wide{margin:0 auto}.f-pre,.f-wide{text-align:left}.f-pre{overflow:hidden;white-space:pre-wrap;word-wrap:break-word;word-break:break-all}.f-cursor-p{cursor:pointer}.f-text-overflow{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.f-f12{font-size:12px}.f-f14{font-size:14px}.f-f16{font-size:16px}.f-f18{font-size:18px}

4
dolphinscheduler-ui/src/3rdcss/show-hint.min.css vendored

@ -1,4 +0,0 @@
/*
* Licensed MIT
*/
.CodeMirror-hints{position:absolute;z-index:10;overflow:hidden;list-style:none;margin:0;padding:2px;-webkit-box-shadow:2px 3px 5px rgba(0,0,0,.2);-moz-box-shadow:2px 3px 5px rgba(0,0,0,.2);box-shadow:2px 3px 5px rgba(0,0,0,.2);border-radius:3px;border:1px solid silver;background:#fff;font-size:90%;font-family:monospace;max-height:20em;overflow-y:auto}.CodeMirror-hint{margin:0;padding:0 4px;border-radius:2px;white-space:pre;color:#000;cursor:pointer}li.CodeMirror-hint-active{background:#08f;color:#fff}

5
dolphinscheduler-ui/src/3rdcss/vs.min.css vendored

@ -1,5 +0,0 @@
/*
* Licensed MIT
*/
.hljs{display:block;overflow-x:auto;padding:0.5em;background:white;color:black}.hljs-comment,.hljs-quote,.hljs-variable{color:#008000}.hljs-keyword,.hljs-selector-tag,.hljs-built_in,.hljs-name,.hljs-tag{color:#00f}.hljs-string,.hljs-title,.hljs-section,.hljs-attribute,.hljs-literal,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-addition{color:#a31515}.hljs-deletion,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-meta{color:#2b91af}.hljs-doctag{color:#808080}.hljs-attr{color:#f00}.hljs-symbol,.hljs-bullet,.hljs-link{color:#00b0e8}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}

7
dolphinscheduler-ui/src/3rdjs/bootstrap.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/canvg.min.js vendored

File diff suppressed because one or more lines are too long

7
dolphinscheduler-ui/src/3rdjs/clipboard.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/codemirror.min.js vendored

File diff suppressed because one or more lines are too long

8
dolphinscheduler-ui/src/3rdjs/d3.min.js vendored

File diff suppressed because one or more lines are too long

1
dolphinscheduler-ui/src/3rdjs/dayjs.min.js vendored

File diff suppressed because one or more lines are too long

21
dolphinscheduler-ui/src/3rdjs/echarts.min.js vendored

File diff suppressed because one or more lines are too long

7
dolphinscheduler-ui/src/3rdjs/es5-sham.min.js vendored

File diff suppressed because one or more lines are too long

7
dolphinscheduler-ui/src/3rdjs/es5-shim.min.js vendored

File diff suppressed because one or more lines are too long

8
dolphinscheduler-ui/src/3rdjs/html2canvas.min.js vendored

File diff suppressed because one or more lines are too long

13
dolphinscheduler-ui/src/3rdjs/jquery-ui.min.js vendored

File diff suppressed because one or more lines are too long

2
dolphinscheduler-ui/src/3rdjs/jquery.min.js vendored

File diff suppressed because one or more lines are too long

10
dolphinscheduler-ui/src/3rdjs/jsplumb.min.js vendored

File diff suppressed because one or more lines are too long

138
dolphinscheduler-ui/src/3rdjs/lodash.min.js vendored

@ -1,138 +0,0 @@
/**
* @license
* Lodash <https://lodash.com/>
* Copyright JS Foundation and other contributors <https://js.foundation/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function r(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&t(n[r],r,n)!==!1;);return n}function e(n,t){for(var r=null==n?0:n.length;r--&&t(n[r],r,n)!==!1;);return n}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return!1;
return!0}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!!(null==n?0:n.length)&&y(n,t,0)>-1}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return!0;return!1}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return!0;return!1}function p(n){return n.split("")}function _(n){return n.match(Tt)||[]}function v(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,!1}),e}function g(n,t,r,e){for(var u=n.length,i=r+(e?1:-1);e?i--:++i<u;)if(t(n[i],i,n))return i;return-1}function y(n,t,r){return t===t?Z(n,t,r):g(n,b,r)}function d(n,t,r,e){
for(var u=r-1,i=n.length;++u<i;)if(e(n[u],t))return u;return-1}function b(n){return n!==n}function w(n,t){var r=null==n?0:n.length;return r?k(n,t)/r:Wn}function m(n){return function(t){return null==t?Q:t[n]}}function x(n){return function(t){return null==n?Q:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=!1,n):t(r,n,u,i)}),r}function A(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].value;return n}function k(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==Q&&(r=r===Q?i:r+i);
}return r}function O(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function I(n,t){return c(t,function(t){return[t,n[t]]})}function R(n){return function(t){return n(t)}}function z(n,t){return c(t,function(t){return n[t]})}function E(n,t){return n.has(t)}function S(n,t){for(var r=-1,e=n.length;++r<e&&y(t,n[r],0)>-1;);return r}function W(n,t){for(var r=n.length;r--&&y(t,n[r],0)>-1;);return r}function L(n,t){for(var r=n.length,e=0;r--;)n[r]===t&&++e;return e}function C(n){return"\\"+Hr[n]}function U(n,t){
return null==n?Q:n[t]}function B(n){return Mr.test(n)}function T(n){return Fr.test(n)}function $(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}function D(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function M(n,t){return function(r){return n(t(r))}}function F(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&o!==on||(n[r]=on,i[u++]=r)}return i}function N(n,t){return"__proto__"==t?Q:n[t]}function P(n){var t=-1,r=Array(n.size);return n.forEach(function(n){
r[++t]=n}),r}function q(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function Z(n,t,r){for(var e=r-1,u=n.length;++e<u;)if(n[e]===t)return e;return-1}function K(n,t,r){for(var e=r+1;e--;)if(n[e]===t)return e;return e}function V(n){return B(n)?H(n):he(n)}function G(n){return B(n)?J(n):p(n)}function H(n){for(var t=$r.lastIndex=0;$r.test(n);)++t;return t}function J(n){return n.match($r)||[]}function Y(n){return n.match(Dr)||[]}var Q,X="4.17.5",nn=200,tn="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",rn="Expected a function",en="__lodash_hash_undefined__",un=500,on="__lodash_placeholder__",fn=1,cn=2,an=4,ln=1,sn=2,hn=1,pn=2,_n=4,vn=8,gn=16,yn=32,dn=64,bn=128,wn=256,mn=512,xn=30,jn="...",An=800,kn=16,On=1,In=2,Rn=3,zn=1/0,En=9007199254740991,Sn=1.7976931348623157e308,Wn=NaN,Ln=4294967295,Cn=Ln-1,Un=Ln>>>1,Bn=[["ary",bn],["bind",hn],["bindKey",pn],["curry",vn],["curryRight",gn],["flip",mn],["partial",yn],["partialRight",dn],["rearg",wn]],Tn="[object Arguments]",$n="[object Array]",Dn="[object AsyncFunction]",Mn="[object Boolean]",Fn="[object Date]",Nn="[object DOMException]",Pn="[object Error]",qn="[object Function]",Zn="[object GeneratorFunction]",Kn="[object Map]",Vn="[object Number]",Gn="[object Null]",Hn="[object Object]",Jn="[object Promise]",Yn="[object Proxy]",Qn="[object RegExp]",Xn="[object Set]",nt="[object String]",tt="[object Symbol]",rt="[object Undefined]",et="[object WeakMap]",ut="[object WeakSet]",it="[object ArrayBuffer]",ot="[object DataView]",ft="[object Float32Array]",ct="[object Float64Array]",at="[object Int8Array]",lt="[object Int16Array]",st="[object Int32Array]",ht="[object Uint8Array]",pt="[object Uint8ClampedArray]",_t="[object Uint16Array]",vt="[object Uint32Array]",gt=/\b__p \+= '';/g,yt=/\b(__p \+=) '' \+/g,dt=/(__e\(.*?\)|\b__t\)) \+\n'';/g,bt=/&(?:amp|lt|gt|quot|#39);/g,wt=/[&<>"']/g,mt=RegExp(bt.source),xt=RegExp(wt.source),jt=/<%-([\s\S]+?)%>/g,At=/<%([\s\S]+?)%>/g,kt=/<%=([\s\S]+?)%>/g,Ot=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,It=/^\w*$/,Rt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,zt=/[\\^$.*+?()[\]{}|]/g,Et=RegExp(zt.source),St=/^\s+|\s+$/g,Wt=/^\s+/,Lt=/\s+$/,Ct=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Ut=/\{\n\/\* \[wrapped with (.+)\] \*/,Bt=/,? & /,Tt=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,$t=/\\(\\)?/g,Dt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Mt=/\w*$/,Ft=/^[-+]0x[0-9a-f]+$/i,Nt=/^0b[01]+$/i,Pt=/^\[object .+?Constructor\]$/,qt=/^0o[0-7]+$/i,Zt=/^(?:0|[1-9]\d*)$/,Kt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Vt=/($^)/,Gt=/['\n\r\u2028\u2029\\]/g,Ht="\\ud800-\\udfff",Jt="\\u0300-\\u036f",Yt="\\ufe20-\\ufe2f",Qt="\\u20d0-\\u20ff",Xt=Jt+Yt+Qt,nr="\\u2700-\\u27bf",tr="a-z\\xdf-\\xf6\\xf8-\\xff",rr="\\xac\\xb1\\xd7\\xf7",er="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",ur="\\u2000-\\u206f",ir=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",or="A-Z\\xc0-\\xd6\\xd8-\\xde",fr="\\ufe0e\\ufe0f",cr=rr+er+ur+ir,ar="['\u2019]",lr="["+Ht+"]",sr="["+cr+"]",hr="["+Xt+"]",pr="\\d+",_r="["+nr+"]",vr="["+tr+"]",gr="[^"+Ht+cr+pr+nr+tr+or+"]",yr="\\ud83c[\\udffb-\\udfff]",dr="(?:"+hr+"|"+yr+")",br="[^"+Ht+"]",wr="(?:\\ud83c[\\udde6-\\uddff]){2}",mr="[\\ud800-\\udbff][\\udc00-\\udfff]",xr="["+or+"]",jr="\\u200d",Ar="(?:"+vr+"|"+gr+")",kr="(?:"+xr+"|"+gr+")",Or="(?:"+ar+"(?:d|ll|m|re|s|t|ve))?",Ir="(?:"+ar+"(?:D|LL|M|RE|S|T|VE))?",Rr=dr+"?",zr="["+fr+"]?",Er="(?:"+jr+"(?:"+[br,wr,mr].join("|")+")"+zr+Rr+")*",Sr="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",Wr="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",Lr=zr+Rr+Er,Cr="(?:"+[_r,wr,mr].join("|")+")"+Lr,Ur="(?:"+[br+hr+"?",hr,wr,mr,lr].join("|")+")",Br=RegExp(ar,"g"),Tr=RegExp(hr,"g"),$r=RegExp(yr+"(?="+yr+")|"+Ur+Lr,"g"),Dr=RegExp([xr+"?"+vr+"+"+Or+"(?="+[sr,xr,"$"].join("|")+")",kr+"+"+Ir+"(?="+[sr,xr+Ar,"$"].join("|")+")",xr+"?"+Ar+"+"+Or,xr+"+"+Ir,Wr,Sr,pr,Cr].join("|"),"g"),Mr=RegExp("["+jr+Ht+Xt+fr+"]"),Fr=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Nr=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Pr=-1,qr={};
qr[ft]=qr[ct]=qr[at]=qr[lt]=qr[st]=qr[ht]=qr[pt]=qr[_t]=qr[vt]=!0,qr[Tn]=qr[$n]=qr[it]=qr[Mn]=qr[ot]=qr[Fn]=qr[Pn]=qr[qn]=qr[Kn]=qr[Vn]=qr[Hn]=qr[Qn]=qr[Xn]=qr[nt]=qr[et]=!1;var Zr={};Zr[Tn]=Zr[$n]=Zr[it]=Zr[ot]=Zr[Mn]=Zr[Fn]=Zr[ft]=Zr[ct]=Zr[at]=Zr[lt]=Zr[st]=Zr[Kn]=Zr[Vn]=Zr[Hn]=Zr[Qn]=Zr[Xn]=Zr[nt]=Zr[tt]=Zr[ht]=Zr[pt]=Zr[_t]=Zr[vt]=!0,Zr[Pn]=Zr[qn]=Zr[et]=!1;var Kr={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a",
"\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae",
"\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g",
"\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O",
"\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w",
"\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"},Vr={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},Gr={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"},Hr={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Jr=parseFloat,Yr=parseInt,Qr="object"==typeof global&&global&&global.Object===Object&&global,Xr="object"==typeof self&&self&&self.Object===Object&&self,ne=Qr||Xr||Function("return this")(),te="object"==typeof exports&&exports&&!exports.nodeType&&exports,re=te&&"object"==typeof module&&module&&!module.nodeType&&module,ee=re&&re.exports===te,ue=ee&&Qr.process,ie=function(){
try{return ue&&ue.binding&&ue.binding("util")}catch(n){}}(),oe=ie&&ie.isArrayBuffer,fe=ie&&ie.isDate,ce=ie&&ie.isMap,ae=ie&&ie.isRegExp,le=ie&&ie.isSet,se=ie&&ie.isTypedArray,he=m("length"),pe=x(Kr),_e=x(Vr),ve=x(Gr),ge=function p(x){function Z(n){if(oc(n)&&!yh(n)&&!(n instanceof Tt)){if(n instanceof J)return n;if(yl.call(n,"__wrapped__"))return to(n)}return new J(n)}function H(){}function J(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=Q}function Tt(n){
this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Ln,this.__views__=[]}function Ht(){var n=new Tt(this.__wrapped__);return n.__actions__=Bu(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Bu(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Bu(this.__views__),n}function Jt(){if(this.__filtered__){var n=new Tt(this);n.__dir__=-1,n.__filtered__=!0}else n=this.clone(),n.__dir__*=-1;
return n}function Yt(){var n=this.__wrapped__.value(),t=this.__dir__,r=yh(n),e=t<0,u=r?n.length:0,i=ki(0,u,this.__views__),o=i.start,f=i.end,c=f-o,a=e?f:o-1,l=this.__iteratees__,s=l.length,h=0,p=Vl(c,this.__takeCount__);if(!r||!e&&u==c&&p==c)return bu(n,this.__actions__);var _=[];n:for(;c--&&h<p;){a+=t;for(var v=-1,g=n[a];++v<s;){var y=l[v],d=y.iteratee,b=y.type,w=d(g);if(b==In)g=w;else if(!w){if(b==On)continue n;break n}}_[h++]=g}return _}function Qt(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){
var e=n[t];this.set(e[0],e[1])}}function Xt(){this.__data__=es?es(null):{},this.size=0}function nr(n){var t=this.has(n)&&delete this.__data__[n];return this.size-=t?1:0,t}function tr(n){var t=this.__data__;if(es){var r=t[n];return r===en?Q:r}return yl.call(t,n)?t[n]:Q}function rr(n){var t=this.__data__;return es?t[n]!==Q:yl.call(t,n)}function er(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=es&&t===Q?en:t,this}function ur(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){
var e=n[t];this.set(e[0],e[1])}}function ir(){this.__data__=[],this.size=0}function or(n){var t=this.__data__,r=Sr(t,n);return!(r<0)&&(r==t.length-1?t.pop():Sl.call(t,r,1),--this.size,!0)}function fr(n){var t=this.__data__,r=Sr(t,n);return r<0?Q:t[r][1]}function cr(n){return Sr(this.__data__,n)>-1}function ar(n,t){var r=this.__data__,e=Sr(r,n);return e<0?(++this.size,r.push([n,t])):r[e][1]=t,this}function lr(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}
}function sr(){this.size=0,this.__data__={hash:new Qt,map:new(Xl||ur),string:new Qt}}function hr(n){var t=mi(this,n).delete(n);return this.size-=t?1:0,t}function pr(n){return mi(this,n).get(n)}function _r(n){return mi(this,n).has(n)}function vr(n,t){var r=mi(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this}function gr(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new lr;++t<r;)this.add(n[t])}function yr(n){return this.__data__.set(n,en),this}function dr(n){return this.__data__.has(n);
}function br(n){this.size=(this.__data__=new ur(n)).size}function wr(){this.__data__=new ur,this.size=0}function mr(n){var t=this.__data__,r=t.delete(n);return this.size=t.size,r}function xr(n){return this.__data__.get(n)}function jr(n){return this.__data__.has(n)}function Ar(n,t){var r=this.__data__;if(r instanceof ur){var e=r.__data__;if(!Xl||e.length<nn-1)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new lr(e)}return r.set(n,t),this.size=r.size,this}function kr(n,t){var r=yh(n),e=!r&&gh(n),u=!r&&!e&&bh(n),i=!r&&!e&&!u&&Ah(n),o=r||e||u||i,f=o?O(n.length,ll):[],c=f.length;
for(var a in n)!t&&!yl.call(n,a)||o&&("length"==a||u&&("offset"==a||"parent"==a)||i&&("buffer"==a||"byteLength"==a||"byteOffset"==a)||Li(a,c))||f.push(a);return f}function Or(n){var t=n.length;return t?n[nu(0,t-1)]:Q}function Ir(n,t){return Yi(Bu(n),Dr(t,0,n.length))}function Rr(n){return Yi(Bu(n))}function zr(n,t,r){(r===Q||Kf(n[t],r))&&(r!==Q||t in n)||Ur(n,t,r)}function Er(n,t,r){var e=n[t];yl.call(n,t)&&Kf(e,r)&&(r!==Q||t in n)||Ur(n,t,r)}function Sr(n,t){for(var r=n.length;r--;)if(Kf(n[r][0],t))return r;
return-1}function Wr(n,t,r,e){return vs(n,function(n,u,i){t(e,n,r(n),i)}),e}function Lr(n,t){return n&&Tu(t,Fc(t),n)}function Cr(n,t){return n&&Tu(t,Nc(t),n)}function Ur(n,t,r){"__proto__"==t&&Ul?Ul(n,t,{configurable:!0,enumerable:!0,value:r,writable:!0}):n[t]=r}function $r(n,t){for(var r=-1,e=t.length,u=el(e),i=null==n;++r<e;)u[r]=i?Q:$c(n,t[r]);return u}function Dr(n,t,r){return n===n&&(r!==Q&&(n=n<=r?n:r),t!==Q&&(n=n>=t?n:t)),n}function Mr(n,t,e,u,i,o){var f,c=t&fn,a=t&cn,l=t&an;if(e&&(f=i?e(n,u,i,o):e(n)),
f!==Q)return f;if(!ic(n))return n;var s=yh(n);if(s){if(f=Ri(n),!c)return Bu(n,f)}else{var h=Is(n),p=h==qn||h==Zn;if(bh(n))return Ou(n,c);if(h==Hn||h==Tn||p&&!i){if(f=a||p?{}:zi(n),!c)return a?Du(n,Cr(f,n)):$u(n,Lr(f,n))}else{if(!Zr[h])return i?n:{};f=Ei(n,h,c)}}o||(o=new br);var _=o.get(n);if(_)return _;if(o.set(n,f),jh(n))return n.forEach(function(r){f.add(Mr(r,t,e,r,n,o))}),f;if(mh(n))return n.forEach(function(r,u){f.set(u,Mr(r,t,e,u,n,o))}),f;var v=l?a?yi:gi:a?Nc:Fc,g=s?Q:v(n);return r(g||n,function(r,u){
g&&(u=r,r=n[u]),Er(f,u,Mr(r,t,e,u,n,o))}),f}function Fr(n){var t=Fc(n);return function(r){return Kr(r,n,t)}}function Kr(n,t,r){var e=r.length;if(null==n)return!e;for(n=cl(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===Q&&!(u in n)||!i(o))return!1}return!0}function Vr(n,t,r){if("function"!=typeof n)throw new sl(rn);return Es(function(){n.apply(Q,r)},t)}function Gr(n,t,r,e){var u=-1,i=o,a=!0,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,R(r))),e?(i=f,a=!1):t.length>=nn&&(i=E,a=!1,t=new gr(t));n:for(;++u<l;){
var p=n[u],_=null==r?p:r(p);if(p=e||0!==p?p:0,a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function Hr(n,t){var r=!0;return vs(n,function(n,e,u){return r=!!t(n,e,u)}),r}function Qr(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===Q?o===o&&!yc(o):r(o,f)))var f=o,c=i}return c}function Xr(n,t,r,e){var u=n.length;for(r=jc(r),r<0&&(r=-r>u?0:u+r),e=e===Q||e>u?u:jc(e),e<0&&(e+=u),e=r>e?0:Ac(e);r<e;)n[r++]=t;return n}function te(n,t){
var r=[];return vs(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function re(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Wi),u||(u=[]);++i<o;){var f=n[i];t>0&&r(f)?t>1?re(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function ue(n,t){return n&&ys(n,t,Fc)}function ie(n,t){return n&&ds(n,t,Fc)}function he(n,t){return i(t,function(t){return rc(n[t])})}function ge(n,t){t=Au(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Qi(t[r++])];return r&&r==e?n:Q}function de(n,t,r){var e=t(n);return yh(n)?e:a(e,r(n))}function be(n){
return null==n?n===Q?rt:Gn:Cl&&Cl in cl(n)?Ai(n):Zi(n)}function we(n,t){return n>t}function me(n,t){return null!=n&&yl.call(n,t)}function xe(n,t){return null!=n&&t in cl(n)}function je(n,t,r){return n>=Vl(t,r)&&n<Kl(t,r)}function Ae(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=el(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,R(t))),s=Vl(p.length,s),l[a]=!r&&(t||u>=120&&p.length>=120)?new gr(a&&p):Q}p=n[0];var _=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],y=t?t(g):g;if(g=r||0!==g?g:0,!(v?E(v,y):e(h,y,r))){
for(a=i;--a;){var d=l[a];if(!(d?E(d,y):e(n[a],y,r)))continue n}v&&v.push(y),h.push(g)}}return h}function ke(n,t,r,e){return ue(n,function(n,u,i){t(e,r(n),u,i)}),e}function Oe(t,r,e){r=Au(r,t),t=Vi(t,r);var u=null==t?t:t[Qi(mo(r))];return null==u?Q:n(u,t,e)}function Ie(n){return oc(n)&&be(n)==Tn}function Re(n){return oc(n)&&be(n)==it}function ze(n){return oc(n)&&be(n)==Fn}function Ee(n,t,r,e,u){return n===t||(null==n||null==t||!oc(n)&&!oc(t)?n!==n&&t!==t:Se(n,t,r,e,Ee,u))}function Se(n,t,r,e,u,i){
var o=yh(n),f=yh(t),c=o?$n:Is(n),a=f?$n:Is(t);c=c==Tn?Hn:c,a=a==Tn?Hn:a;var l=c==Hn,s=a==Hn,h=c==a;if(h&&bh(n)){if(!bh(t))return!1;o=!0,l=!1}if(h&&!l)return i||(i=new br),o||Ah(n)?hi(n,t,r,e,u,i):pi(n,t,c,r,e,u,i);if(!(r&ln)){var p=l&&yl.call(n,"__wrapped__"),_=s&&yl.call(t,"__wrapped__");if(p||_){var v=p?n.value():n,g=_?t.value():t;return i||(i=new br),u(v,g,r,e,i)}}return!!h&&(i||(i=new br),_i(n,t,r,e,u,i))}function We(n){return oc(n)&&Is(n)==Kn}function Le(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;
for(n=cl(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++u<i;){f=r[u];var c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===Q&&!(c in n))return!1}else{var s=new br;if(e)var h=e(a,l,c,n,t,s);if(!(h===Q?Ee(l,a,ln|sn,e,s):h))return!1}}return!0}function Ce(n){return!(!ic(n)||$i(n))&&(rc(n)?jl:Pt).test(Xi(n))}function Ue(n){return oc(n)&&be(n)==Qn}function Be(n){return oc(n)&&Is(n)==Xn}function Te(n){return oc(n)&&uc(n.length)&&!!qr[be(n)]}function $e(n){return"function"==typeof n?n:null==n?Sa:"object"==typeof n?yh(n)?qe(n[0],n[1]):Pe(n):Da(n);
}function De(n){if(!Di(n))return Zl(n);var t=[];for(var r in cl(n))yl.call(n,r)&&"constructor"!=r&&t.push(r);return t}function Me(n){if(!ic(n))return qi(n);var t=Di(n),r=[];for(var e in n)("constructor"!=e||!t&&yl.call(n,e))&&r.push(e);return r}function Fe(n,t){return n<t}function Ne(n,t){var r=-1,e=Vf(n)?el(n.length):[];return vs(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Pe(n){var t=xi(n);return 1==t.length&&t[0][2]?Fi(t[0][0],t[0][1]):function(r){return r===n||Le(r,n,t)}}function qe(n,t){return Ui(n)&&Mi(t)?Fi(Qi(n),t):function(r){
var e=$c(r,n);return e===Q&&e===t?Mc(r,n):Ee(t,e,ln|sn)}}function Ze(n,t,r,e,u){n!==t&&ys(t,function(i,o){if(ic(i))u||(u=new br),Ke(n,t,o,r,Ze,e,u);else{var f=e?e(N(n,o),i,o+"",n,t,u):Q;f===Q&&(f=i),zr(n,o,f)}},Nc)}function Ke(n,t,r,e,u,i,o){var f=N(n,r),c=N(t,r),a=o.get(c);if(a)return zr(n,r,a),Q;var l=i?i(f,c,r+"",n,t,o):Q,s=l===Q;if(s){var h=yh(c),p=!h&&bh(c),_=!h&&!p&&Ah(c);l=c,h||p||_?yh(f)?l=f:Gf(f)?l=Bu(f):p?(s=!1,l=Ou(c,!0)):_?(s=!1,l=Su(c,!0)):l=[]:_c(c)||gh(c)?(l=f,gh(f)?l=Oc(f):(!ic(f)||e&&rc(f))&&(l=zi(c))):s=!1;
}s&&(o.set(c,l),u(l,c,e,i,o),o.delete(c)),zr(n,r,l)}function Ve(n,t){var r=n.length;if(r)return t+=t<0?r:0,Li(t,r)?n[t]:Q}function Ge(n,t,r){var e=-1;return t=c(t.length?t:[Sa],R(wi())),A(Ne(n,function(n,r,u){return{criteria:c(t,function(t){return t(n)}),index:++e,value:n}}),function(n,t){return Lu(n,t,r)})}function He(n,t){return Je(n,t,function(t,r){return Mc(n,r)})}function Je(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=ge(n,o);r(f,o)&&ou(i,Au(o,n),f)}return i}function Ye(n){return function(t){
return ge(t,n)}}function Qe(n,t,r,e){var u=e?d:y,i=-1,o=t.length,f=n;for(n===t&&(t=Bu(t)),r&&(f=c(n,R(r)));++i<o;)for(var a=0,l=t[i],s=r?r(l):l;(a=u(f,s,a,e))>-1;)f!==n&&Sl.call(f,a,1),Sl.call(n,a,1);return n}function Xe(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Li(u)?Sl.call(n,u,1):gu(n,u)}}return n}function nu(n,t){return n+Ml(Jl()*(t-n+1))}function tu(n,t,r,e){for(var u=-1,i=Kl(Dl((t-n)/(r||1)),0),o=el(i);i--;)o[e?i:++u]=n,n+=r;return o}function ru(n,t){var r="";
if(!n||t<1||t>En)return r;do t%2&&(r+=n),t=Ml(t/2),t&&(n+=n);while(t);return r}function eu(n,t){return Ss(Ki(n,t,Sa),n+"")}function uu(n){return Or(na(n))}function iu(n,t){var r=na(n);return Yi(r,Dr(t,0,r.length))}function ou(n,t,r,e){if(!ic(n))return n;t=Au(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=Qi(t[u]),a=r;if(u!=o){var l=f[c];a=e?e(l,c,f):Q,a===Q&&(a=ic(l)?l:Li(t[u+1])?[]:{})}Er(f,c,a),f=f[c]}return n}function fu(n){return Yi(na(n))}function cu(n,t,r){var e=-1,u=n.length;
t<0&&(t=-t>u?0:u+t),r=r>u?u:r,r<0&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0;for(var i=el(u);++e<u;)i[e]=n[e+t];return i}function au(n,t){var r;return vs(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function lu(n,t,r){var e=0,u=null==n?e:n.length;if("number"==typeof t&&t===t&&u<=Un){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!yc(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return su(n,t,Sa,r)}function su(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=yc(t),a=t===Q;u<i;){var l=Ml((u+i)/2),s=r(n[l]),h=s!==Q,p=null===s,_=s===s,v=yc(s);
if(o)var g=e||_;else g=a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):!p&&!v&&(e?s<=t:s<t);g?u=l+1:i=l}return Vl(i,Cn)}function hu(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r],f=t?t(o):o;if(!r||!Kf(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function pu(n){return"number"==typeof n?n:yc(n)?Wn:+n}function _u(n){if("string"==typeof n)return n;if(yh(n))return c(n,_u)+"";if(yc(n))return ps?ps.call(n):"";var t=n+"";return"0"==t&&1/n==-zn?"-0":t}function vu(n,t,r){var e=-1,u=o,i=n.length,c=!0,a=[],l=a;
if(r)c=!1,u=f;else if(i>=nn){var s=t?null:js(n);if(s)return P(s);c=!1,u=E,l=new gr}else l=t?[]:a;n:for(;++e<i;){var h=n[e],p=t?t(h):h;if(h=r||0!==h?h:0,c&&p===p){for(var _=l.length;_--;)if(l[_]===p)continue n;t&&l.push(p),a.push(h)}else u(l,p,r)||(l!==a&&l.push(p),a.push(h))}return a}function gu(n,t){return t=Au(t,n),n=Vi(n,t),null==n||delete n[Qi(mo(t))]}function yu(n,t,r,e){return ou(n,t,r(ge(n,t)),e)}function du(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?cu(n,e?0:i,e?i+1:u):cu(n,e?i+1:0,e?u:i);
}function bu(n,t){var r=n;return r instanceof Tt&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function wu(n,t,r){var e=n.length;if(e<2)return e?vu(n[0]):[];for(var u=-1,i=el(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=Gr(i[u]||o,n[f],t,r));return vu(re(i,1),t,r)}function mu(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;){r(o,n[e],e<i?t[e]:Q)}return o}function xu(n){return Gf(n)?n:[]}function ju(n){return"function"==typeof n?n:Sa}function Au(n,t){return yh(n)?n:Ui(n,t)?[n]:Ws(Rc(n));
}function ku(n,t,r){var e=n.length;return r=r===Q?e:r,!t&&r>=e?n:cu(n,t,r)}function Ou(n,t){if(t)return n.slice();var r=n.length,e=Il?Il(r):new n.constructor(r);return n.copy(e),e}function Iu(n){var t=new n.constructor(n.byteLength);return new Ol(t).set(new Ol(n)),t}function Ru(n,t){return new n.constructor(t?Iu(n.buffer):n.buffer,n.byteOffset,n.byteLength)}function zu(n){var t=new n.constructor(n.source,Mt.exec(n));return t.lastIndex=n.lastIndex,t}function Eu(n){return hs?cl(hs.call(n)):{}}function Su(n,t){
return new n.constructor(t?Iu(n.buffer):n.buffer,n.byteOffset,n.length)}function Wu(n,t){if(n!==t){var r=n!==Q,e=null===n,u=n===n,i=yc(n),o=t!==Q,f=null===t,c=t===t,a=yc(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Lu(n,t,r){for(var e=-1,u=n.criteria,i=t.criteria,o=u.length,f=r.length;++e<o;){var c=Wu(u[e],i[e]);if(c){if(e>=f)return c;return c*("desc"==r[e]?-1:1)}}return n.index-t.index}function Cu(n,t,r,e){
for(var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Kl(i-o,0),l=el(c+a),s=!e;++f<c;)l[f]=t[f];for(;++u<o;)(s||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Uu(n,t,r,e){for(var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Kl(i-f,0),s=el(l+a),h=!e;++u<l;)s[u]=n[u];for(var p=u;++c<a;)s[p+c]=t[c];for(;++o<f;)(h||u<i)&&(s[p+r[o]]=n[u++]);return s}function Bu(n,t){var r=-1,e=n.length;for(t||(t=el(e));++r<e;)t[r]=n[r];return t}function Tu(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){
var f=t[i],c=e?e(r[f],n[f],f,r,n):Q;c===Q&&(c=n[f]),u?Ur(r,f,c):Er(r,f,c)}return r}function $u(n,t){return Tu(n,ks(n),t)}function Du(n,t){return Tu(n,Os(n),t)}function Mu(n,r){return function(e,u){var i=yh(e)?t:Wr,o=r?r():{};return i(e,n,wi(u,2),o)}}function Fu(n){return eu(function(t,r){var e=-1,u=r.length,i=u>1?r[u-1]:Q,o=u>2?r[2]:Q;for(i=n.length>3&&"function"==typeof i?(u--,i):Q,o&&Ci(r[0],r[1],o)&&(i=u<3?Q:i,u=1),t=cl(t);++e<u;){var f=r[e];f&&n(t,f,e,i)}return t})}function Nu(n,t){return function(r,e){
if(null==r)return r;if(!Vf(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=cl(r);(t?i--:++i<u)&&e(o[i],i,o)!==!1;);return r}}function Pu(n){return function(t,r,e){for(var u=-1,i=cl(t),o=e(t),f=o.length;f--;){var c=o[n?f:++u];if(r(i[c],c,i)===!1)break}return t}}function qu(n,t,r){function e(){return(this&&this!==ne&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=t&hn,i=Vu(n);return e}function Zu(n){return function(t){t=Rc(t);var r=B(t)?G(t):Q,e=r?r[0]:t.charAt(0),u=r?ku(r,1).join(""):t.slice(1);
return e[n]()+u}}function Ku(n){return function(t){return l(Oa(oa(t).replace(Br,"")),n,"")}}function Vu(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=_s(n.prototype),e=n.apply(r,t);
return ic(e)?e:r}}function Gu(t,r,e){function u(){for(var o=arguments.length,f=el(o),c=o,a=bi(u);c--;)f[c]=arguments[c];var l=o<3&&f[0]!==a&&f[o-1]!==a?[]:F(f,a);return o-=l.length,o<e?ii(t,r,Yu,u.placeholder,Q,f,l,Q,Q,e-o):n(this&&this!==ne&&this instanceof u?i:t,this,f)}var i=Vu(t);return u}function Hu(n){return function(t,r,e){var u=cl(t);if(!Vf(t)){var i=wi(r,3);t=Fc(t),r=function(n){return i(u[n],n,u)}}var o=n(t,r,e);return o>-1?u[i?t[o]:o]:Q}}function Ju(n){return vi(function(t){var r=t.length,e=r,u=J.prototype.thru;
for(n&&t.reverse();e--;){var i=t[e];if("function"!=typeof i)throw new sl(rn);if(u&&!o&&"wrapper"==di(i))var o=new J([],!0)}for(e=o?e:r;++e<r;){i=t[e];var f=di(i),c="wrapper"==f?As(i):Q;o=c&&Ti(c[0])&&c[1]==(bn|vn|yn|wn)&&!c[4].length&&1==c[9]?o[di(c[0])].apply(o,c[3]):1==i.length&&Ti(i)?o[f]():o.thru(i)}return function(){var n=arguments,e=n[0];if(o&&1==n.length&&yh(e))return o.plant(e).value();for(var u=0,i=r?t[u].apply(this,n):e;++u<r;)i=t[u].call(this,i);return i}})}function Yu(n,t,r,e,u,i,o,f,c,a){
function l(){for(var y=arguments.length,d=el(y),b=y;b--;)d[b]=arguments[b];if(_)var w=bi(l),m=L(d,w);if(e&&(d=Cu(d,e,u,_)),i&&(d=Uu(d,i,o,_)),y-=m,_&&y<a){return ii(n,t,Yu,l.placeholder,r,d,F(d,w),f,c,a-y)}var x=h?r:this,j=p?x[n]:n;return y=d.length,f?d=Gi(d,f):v&&y>1&&d.reverse(),s&&c<y&&(d.length=c),this&&this!==ne&&this instanceof l&&(j=g||Vu(j)),j.apply(x,d)}var s=t&bn,h=t&hn,p=t&pn,_=t&(vn|gn),v=t&mn,g=p?Q:Vu(n);return l}function Qu(n,t){return function(r,e){return ke(r,n,t(e),{})}}function Xu(n,t){
return function(r,e){var u;if(r===Q&&e===Q)return t;if(r!==Q&&(u=r),e!==Q){if(u===Q)return e;"string"==typeof r||"string"==typeof e?(r=_u(r),e=_u(e)):(r=pu(r),e=pu(e)),u=n(r,e)}return u}}function ni(t){return vi(function(r){return r=c(r,R(wi())),eu(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ti(n,t){t=t===Q?" ":_u(t);var r=t.length;if(r<2)return r?ru(t,n):t;var e=ru(t,Dl(n/V(t)));return B(t)?ku(G(e),0,n).join(""):e.slice(0,n)}function ri(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=el(l+c),h=this&&this!==ne&&this instanceof i?f:t;++a<l;)s[a]=u[a];
for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=r&hn,f=Vu(t);return i}function ei(n){return function(t,r,e){return e&&"number"!=typeof e&&Ci(t,r,e)&&(r=e=Q),t=xc(t),r===Q?(r=t,t=0):r=xc(r),e=e===Q?t<r?1:-1:xc(e),tu(t,r,e,n)}}function ui(n){return function(t,r){return"string"==typeof t&&"string"==typeof r||(t=kc(t),r=kc(r)),n(t,r)}}function ii(n,t,r,e,u,i,o,f,c,a){var l=t&vn,s=l?o:Q,h=l?Q:o,p=l?i:Q,_=l?Q:i;t|=l?yn:dn,t&=~(l?dn:yn),t&_n||(t&=~(hn|pn));var v=[n,t,u,p,s,_,h,f,c,a],g=r.apply(Q,v);
return Ti(n)&&zs(g,v),g.placeholder=e,Hi(g,n,t)}function oi(n){var t=fl[n];return function(n,r){if(n=kc(n),r=null==r?0:Vl(jc(r),292)){var e=(Rc(n)+"e").split("e");return e=(Rc(t(e[0]+"e"+(+e[1]+r)))+"e").split("e"),+(e[0]+"e"+(+e[1]-r))}return t(n)}}function fi(n){return function(t){var r=Is(t);return r==Kn?D(t):r==Xn?q(t):I(t,n(t))}}function ci(n,t,r,e,u,i,o,f){var c=t&pn;if(!c&&"function"!=typeof n)throw new sl(rn);var a=e?e.length:0;if(a||(t&=~(yn|dn),e=u=Q),o=o===Q?o:Kl(jc(o),0),f=f===Q?f:jc(f),
a-=u?u.length:0,t&dn){var l=e,s=u;e=u=Q}var h=c?Q:As(n),p=[n,t,r,e,u,l,s,i,o,f];if(h&&Pi(p,h),n=p[0],t=p[1],r=p[2],e=p[3],u=p[4],f=p[9]=p[9]===Q?c?0:n.length:Kl(p[9]-a,0),!f&&t&(vn|gn)&&(t&=~(vn|gn)),t&&t!=hn)_=t==vn||t==gn?Gu(n,t,f):t!=yn&&t!=(hn|yn)||u.length?Yu.apply(Q,p):ri(n,t,r,e);else var _=qu(n,t,r);return Hi((h?bs:zs)(_,p),n,t)}function ai(n,t,r,e){return n===Q||Kf(n,_l[r])&&!yl.call(e,r)?t:n}function li(n,t,r,e,u,i){return ic(n)&&ic(t)&&(i.set(t,n),Ze(n,t,Q,li,i),i.delete(t)),n}function si(n){
return _c(n)?Q:n}function hi(n,t,r,e,u,i){var o=r&ln,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return!1;var a=i.get(n);if(a&&i.get(t))return a==t;var l=-1,s=!0,p=r&sn?new gr:Q;for(i.set(n,t),i.set(t,n);++l<f;){var _=n[l],v=t[l];if(e)var g=o?e(v,_,l,t,n,i):e(_,v,l,n,t,i);if(g!==Q){if(g)continue;s=!1;break}if(p){if(!h(t,function(n,t){if(!E(p,t)&&(_===n||u(_,n,r,e,i)))return p.push(t)})){s=!1;break}}else if(_!==v&&!u(_,v,r,e,i)){s=!1;break}}return i.delete(n),i.delete(t),s}function pi(n,t,r,e,u,i,o){
switch(r){case ot:if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)return!1;n=n.buffer,t=t.buffer;case it:return!(n.byteLength!=t.byteLength||!i(new Ol(n),new Ol(t)));case Mn:case Fn:case Vn:return Kf(+n,+t);case Pn:return n.name==t.name&&n.message==t.message;case Qn:case nt:return n==t+"";case Kn:var f=D;case Xn:var c=e&ln;if(f||(f=P),n.size!=t.size&&!c)return!1;var a=o.get(n);if(a)return a==t;e|=sn,o.set(n,t);var l=hi(f(n),f(t),e,u,i,o);return o.delete(n),l;case tt:if(hs)return hs.call(n)==hs.call(t);
}return!1}function _i(n,t,r,e,u,i){var o=r&ln,f=gi(n),c=f.length;if(c!=gi(t).length&&!o)return!1;for(var a=c;a--;){var l=f[a];if(!(o?l in t:yl.call(t,l)))return!1}var s=i.get(n);if(s&&i.get(t))return s==t;var h=!0;i.set(n,t),i.set(t,n);for(var p=o;++a<c;){l=f[a];var _=n[l],v=t[l];if(e)var g=o?e(v,_,l,t,n,i):e(_,v,l,n,t,i);if(!(g===Q?_===v||u(_,v,r,e,i):g)){h=!1;break}p||(p="constructor"==l)}if(h&&!p){var y=n.constructor,d=t.constructor;y!=d&&"constructor"in n&&"constructor"in t&&!("function"==typeof y&&y instanceof y&&"function"==typeof d&&d instanceof d)&&(h=!1);
}return i.delete(n),i.delete(t),h}function vi(n){return Ss(Ki(n,Q,ho),n+"")}function gi(n){return de(n,Fc,ks)}function yi(n){return de(n,Nc,Os)}function di(n){for(var t=n.name+"",r=is[t],e=yl.call(is,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function bi(n){return(yl.call(Z,"placeholder")?Z:n).placeholder}function wi(){var n=Z.iteratee||Wa;return n=n===Wa?$e:n,arguments.length?n(arguments[0],arguments[1]):n}function mi(n,t){var r=n.__data__;return Bi(t)?r["string"==typeof t?"string":"hash"]:r.map;
}function xi(n){for(var t=Fc(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,Mi(u)]}return t}function ji(n,t){var r=U(n,t);return Ce(r)?r:Q}function Ai(n){var t=yl.call(n,Cl),r=n[Cl];try{n[Cl]=Q;var e=!0}catch(n){}var u=wl.call(n);return e&&(t?n[Cl]=r:delete n[Cl]),u}function ki(n,t,r){for(var e=-1,u=r.length;++e<u;){var i=r[e],o=i.size;switch(i.type){case"drop":n+=o;break;case"dropRight":t-=o;break;case"take":t=Vl(t,n+o);break;case"takeRight":n=Kl(n,t-o)}}return{start:n,end:t}}function Oi(n){var t=n.match(Ut);
return t?t[1].split(Bt):[]}function Ii(n,t,r){t=Au(t,n);for(var e=-1,u=t.length,i=!1;++e<u;){var o=Qi(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&uc(u)&&Li(o,u)&&(yh(n)||gh(n)))}function Ri(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&yl.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function zi(n){return"function"!=typeof n.constructor||Di(n)?{}:_s(Rl(n))}function Ei(n,t,r){var e=n.constructor;switch(t){case it:return Iu(n);
case Mn:case Fn:return new e(+n);case ot:return Ru(n,r);case ft:case ct:case at:case lt:case st:case ht:case pt:case _t:case vt:return Su(n,r);case Kn:return new e;case Vn:case nt:return new e(n);case Qn:return zu(n);case Xn:return new e;case tt:return Eu(n)}}function Si(n,t){var r=t.length;if(!r)return n;var e=r-1;return t[e]=(r>1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Ct,"{\n/* [wrapped with "+t+"] */\n")}function Wi(n){return yh(n)||gh(n)||!!(Wl&&n&&n[Wl])}function Li(n,t){var r=typeof n;
return t=null==t?En:t,!!t&&("number"==r||"symbol"!=r&&Zt.test(n))&&n>-1&&n%1==0&&n<t}function Ci(n,t,r){if(!ic(r))return!1;var e=typeof t;return!!("number"==e?Vf(r)&&Li(t,r.length):"string"==e&&t in r)&&Kf(r[t],n)}function Ui(n,t){if(yh(n))return!1;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!yc(n))||(It.test(n)||!Ot.test(n)||null!=t&&n in cl(t))}function Bi(n){var t=typeof n;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==n:null===n}function Ti(n){
var t=di(n),r=Z[t];if("function"!=typeof r||!(t in Tt.prototype))return!1;if(n===r)return!0;var e=As(r);return!!e&&n===e[0]}function $i(n){return!!bl&&bl in n}function Di(n){var t=n&&n.constructor;return n===("function"==typeof t&&t.prototype||_l)}function Mi(n){return n===n&&!ic(n)}function Fi(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==Q||n in cl(r)))}}function Ni(n){var t=Wf(n,function(n){return r.size===un&&r.clear(),n}),r=t.cache;return t}function Pi(n,t){var r=n[1],e=t[1],u=r|e,i=u<(hn|pn|bn),o=e==bn&&r==vn||e==bn&&r==wn&&n[7].length<=t[8]||e==(bn|wn)&&t[7].length<=t[8]&&r==vn;
if(!i&&!o)return n;e&hn&&(n[2]=t[2],u|=r&hn?0:_n);var f=t[3];if(f){var c=n[3];n[3]=c?Cu(c,f,t[4]):f,n[4]=c?F(n[3],on):t[4]}return f=t[5],f&&(c=n[5],n[5]=c?Uu(c,f,t[6]):f,n[6]=c?F(n[5],on):t[6]),f=t[7],f&&(n[7]=f),e&bn&&(n[8]=null==n[8]?t[8]:Vl(n[8],t[8])),null==n[9]&&(n[9]=t[9]),n[0]=t[0],n[1]=u,n}function qi(n){var t=[];if(null!=n)for(var r in cl(n))t.push(r);return t}function Zi(n){return wl.call(n)}function Ki(t,r,e){return r=Kl(r===Q?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Kl(u.length-r,0),f=el(o);++i<o;)f[i]=u[r+i];
i=-1;for(var c=el(r+1);++i<r;)c[i]=u[i];return c[r]=e(f),n(t,this,c)}}function Vi(n,t){return t.length<2?n:ge(n,cu(t,0,-1))}function Gi(n,t){for(var r=n.length,e=Vl(t.length,r),u=Bu(n);e--;){var i=t[e];n[e]=Li(i,r)?u[i]:Q}return n}function Hi(n,t,r){var e=t+"";return Ss(n,Si(e,no(Oi(e),r)))}function Ji(n){var t=0,r=0;return function(){var e=Gl(),u=kn-(e-r);if(r=e,u>0){if(++t>=An)return arguments[0]}else t=0;return n.apply(Q,arguments)}}function Yi(n,t){var r=-1,e=n.length,u=e-1;for(t=t===Q?e:t;++r<t;){
var i=nu(r,u),o=n[i];n[i]=n[r],n[r]=o}return n.length=t,n}function Qi(n){if("string"==typeof n||yc(n))return n;var t=n+"";return"0"==t&&1/n==-zn?"-0":t}function Xi(n){if(null!=n){try{return gl.call(n)}catch(n){}try{return n+""}catch(n){}}return""}function no(n,t){return r(Bn,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function to(n){if(n instanceof Tt)return n.clone();var t=new J(n.__wrapped__,n.__chain__);return t.__actions__=Bu(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,
t}function ro(n,t,r){t=(r?Ci(n,t,r):t===Q)?1:Kl(jc(t),0);var e=null==n?0:n.length;if(!e||t<1)return[];for(var u=0,i=0,o=el(Dl(e/t));u<e;)o[i++]=cu(n,u,u+=t);return o}function eo(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){var i=n[t];i&&(u[e++]=i)}return u}function uo(){var n=arguments.length;if(!n)return[];for(var t=el(n-1),r=arguments[0],e=n;e--;)t[e-1]=arguments[e];return a(yh(r)?Bu(r):[r],re(t,1))}function io(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===Q?1:jc(t),cu(n,t<0?0:t,e)):[];
}function oo(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===Q?1:jc(t),t=e-t,cu(n,0,t<0?0:t)):[]}function fo(n,t){return n&&n.length?du(n,wi(t,3),!0,!0):[]}function co(n,t){return n&&n.length?du(n,wi(t,3),!0):[]}function ao(n,t,r,e){var u=null==n?0:n.length;return u?(r&&"number"!=typeof r&&Ci(n,t,r)&&(r=0,e=u),Xr(n,t,r,e)):[]}function lo(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:jc(r);return u<0&&(u=Kl(e+u,0)),g(n,wi(t,3),u)}function so(n,t,r){var e=null==n?0:n.length;if(!e)return-1;
var u=e-1;return r!==Q&&(u=jc(r),u=r<0?Kl(e+u,0):Vl(u,e-1)),g(n,wi(t,3),u,!0)}function ho(n){return(null==n?0:n.length)?re(n,1):[]}function po(n){return(null==n?0:n.length)?re(n,zn):[]}function _o(n,t){return(null==n?0:n.length)?(t=t===Q?1:jc(t),re(n,t)):[]}function vo(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e}function go(n){return n&&n.length?n[0]:Q}function yo(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:jc(r);return u<0&&(u=Kl(e+u,0)),
y(n,t,u)}function bo(n){return(null==n?0:n.length)?cu(n,0,-1):[]}function wo(n,t){return null==n?"":ql.call(n,t)}function mo(n){var t=null==n?0:n.length;return t?n[t-1]:Q}function xo(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;return r!==Q&&(u=jc(r),u=u<0?Kl(e+u,0):Vl(u,e-1)),t===t?K(n,t,u):g(n,b,u,!0)}function jo(n,t){return n&&n.length?Ve(n,jc(t)):Q}function Ao(n,t){return n&&n.length&&t&&t.length?Qe(n,t):n}function ko(n,t,r){return n&&n.length&&t&&t.length?Qe(n,t,wi(r,2)):n}function Oo(n,t,r){
return n&&n.length&&t&&t.length?Qe(n,t,Q,r):n}function Io(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=wi(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return Xe(n,u),r}function Ro(n){return null==n?n:Yl.call(n)}function zo(n,t,r){var e=null==n?0:n.length;return e?(r&&"number"!=typeof r&&Ci(n,t,r)?(t=0,r=e):(t=null==t?0:jc(t),r=r===Q?e:jc(r)),cu(n,t,r)):[]}function Eo(n,t){return lu(n,t)}function So(n,t,r){return su(n,t,wi(r,2))}function Wo(n,t){var r=null==n?0:n.length;
if(r){var e=lu(n,t);if(e<r&&Kf(n[e],t))return e}return-1}function Lo(n,t){return lu(n,t,!0)}function Co(n,t,r){return su(n,t,wi(r,2),!0)}function Uo(n,t){if(null==n?0:n.length){var r=lu(n,t,!0)-1;if(Kf(n[r],t))return r}return-1}function Bo(n){return n&&n.length?hu(n):[]}function To(n,t){return n&&n.length?hu(n,wi(t,2)):[]}function $o(n){var t=null==n?0:n.length;return t?cu(n,1,t):[]}function Do(n,t,r){return n&&n.length?(t=r||t===Q?1:jc(t),cu(n,0,t<0?0:t)):[]}function Mo(n,t,r){var e=null==n?0:n.length;
return e?(t=r||t===Q?1:jc(t),t=e-t,cu(n,t<0?0:t,e)):[]}function Fo(n,t){return n&&n.length?du(n,wi(t,3),!1,!0):[]}function No(n,t){return n&&n.length?du(n,wi(t,3)):[]}function Po(n){return n&&n.length?vu(n):[]}function qo(n,t){return n&&n.length?vu(n,wi(t,2)):[]}function Zo(n,t){return t="function"==typeof t?t:Q,n&&n.length?vu(n,Q,t):[]}function Ko(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(Gf(n))return t=Kl(n.length,t),!0}),O(t,function(t){return c(n,m(t))})}function Vo(t,r){
if(!t||!t.length)return[];var e=Ko(t);return null==r?e:c(e,function(t){return n(r,Q,t)})}function Go(n,t){return mu(n||[],t||[],Er)}function Ho(n,t){return mu(n||[],t||[],ou)}function Jo(n){var t=Z(n);return t.__chain__=!0,t}function Yo(n,t){return t(n),n}function Qo(n,t){return t(n)}function Xo(){return Jo(this)}function nf(){return new J(this.value(),this.__chain__)}function tf(){this.__values__===Q&&(this.__values__=mc(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?Q:this.__values__[this.__index__++]
}}function rf(){return this}function ef(n){for(var t,r=this;r instanceof H;){var e=to(r);e.__index__=0,e.__values__=Q,t?u.__wrapped__=e:t=e;var u=e;r=r.__wrapped__}return u.__wrapped__=n,t}function uf(){var n=this.__wrapped__;if(n instanceof Tt){var t=n;return this.__actions__.length&&(t=new Tt(this)),t=t.reverse(),t.__actions__.push({func:Qo,args:[Ro],thisArg:Q}),new J(t,this.__chain__)}return this.thru(Ro)}function of(){return bu(this.__wrapped__,this.__actions__)}function ff(n,t,r){var e=yh(n)?u:Hr;
return r&&Ci(n,t,r)&&(t=Q),e(n,wi(t,3))}function cf(n,t){return(yh(n)?i:te)(n,wi(t,3))}function af(n,t){return re(vf(n,t),1)}function lf(n,t){return re(vf(n,t),zn)}function sf(n,t,r){return r=r===Q?1:jc(r),re(vf(n,t),r)}function hf(n,t){return(yh(n)?r:vs)(n,wi(t,3))}function pf(n,t){return(yh(n)?e:gs)(n,wi(t,3))}function _f(n,t,r,e){n=Vf(n)?n:na(n),r=r&&!e?jc(r):0;var u=n.length;return r<0&&(r=Kl(u+r,0)),gc(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&y(n,t,r)>-1}function vf(n,t){return(yh(n)?c:Ne)(n,wi(t,3));
}function gf(n,t,r,e){return null==n?[]:(yh(t)||(t=null==t?[]:[t]),r=e?Q:r,yh(r)||(r=null==r?[]:[r]),Ge(n,t,r))}function yf(n,t,r){var e=yh(n)?l:j,u=arguments.length<3;return e(n,wi(t,4),r,u,vs)}function df(n,t,r){var e=yh(n)?s:j,u=arguments.length<3;return e(n,wi(t,4),r,u,gs)}function bf(n,t){return(yh(n)?i:te)(n,Lf(wi(t,3)))}function wf(n){return(yh(n)?Or:uu)(n)}function mf(n,t,r){return t=(r?Ci(n,t,r):t===Q)?1:jc(t),(yh(n)?Ir:iu)(n,t)}function xf(n){return(yh(n)?Rr:fu)(n)}function jf(n){if(null==n)return 0;
if(Vf(n))return gc(n)?V(n):n.length;var t=Is(n);return t==Kn||t==Xn?n.size:De(n).length}function Af(n,t,r){var e=yh(n)?h:au;return r&&Ci(n,t,r)&&(t=Q),e(n,wi(t,3))}function kf(n,t){if("function"!=typeof t)throw new sl(rn);return n=jc(n),function(){if(--n<1)return t.apply(this,arguments)}}function Of(n,t,r){return t=r?Q:t,t=n&&null==t?n.length:t,ci(n,bn,Q,Q,Q,Q,t)}function If(n,t){var r;if("function"!=typeof t)throw new sl(rn);return n=jc(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=Q),
r}}function Rf(n,t,r){t=r?Q:t;var e=ci(n,vn,Q,Q,Q,Q,Q,t);return e.placeholder=Rf.placeholder,e}function zf(n,t,r){t=r?Q:t;var e=ci(n,gn,Q,Q,Q,Q,Q,t);return e.placeholder=zf.placeholder,e}function Ef(n,t,r){function e(t){var r=h,e=p;return h=p=Q,d=t,v=n.apply(e,r)}function u(n){return d=n,g=Es(f,t),b?e(n):v}function i(n){var r=n-y,e=n-d,u=t-r;return w?Vl(u,_-e):u}function o(n){var r=n-y,e=n-d;return y===Q||r>=t||r<0||w&&e>=_}function f(){var n=ih();return o(n)?c(n):(g=Es(f,i(n)),Q)}function c(n){return g=Q,
m&&h?e(n):(h=p=Q,v)}function a(){g!==Q&&xs(g),d=0,h=y=p=g=Q}function l(){return g===Q?v:c(ih())}function s(){var n=ih(),r=o(n);if(h=arguments,p=this,y=n,r){if(g===Q)return u(y);if(w)return g=Es(f,t),e(y)}return g===Q&&(g=Es(f,t)),v}var h,p,_,v,g,y,d=0,b=!1,w=!1,m=!0;if("function"!=typeof n)throw new sl(rn);return t=kc(t)||0,ic(r)&&(b=!!r.leading,w="maxWait"in r,_=w?Kl(kc(r.maxWait)||0,t):_,m="trailing"in r?!!r.trailing:m),s.cancel=a,s.flush=l,s}function Sf(n){return ci(n,mn)}function Wf(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new sl(rn);
var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(Wf.Cache||lr),r}function Lf(n){if("function"!=typeof n)throw new sl(rn);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function Cf(n){return If(2,n)}function Uf(n,t){
if("function"!=typeof n)throw new sl(rn);return t=t===Q?t:jc(t),eu(n,t)}function Bf(t,r){if("function"!=typeof t)throw new sl(rn);return r=null==r?0:Kl(jc(r),0),eu(function(e){var u=e[r],i=ku(e,0,r);return u&&a(i,u),n(t,this,i)})}function Tf(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new sl(rn);return ic(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Ef(n,t,{leading:e,maxWait:t,trailing:u})}function $f(n){return Of(n,1)}function Df(n,t){return sh(ju(t),n)}function Mf(){
if(!arguments.length)return[];var n=arguments[0];return yh(n)?n:[n]}function Ff(n){return Mr(n,an)}function Nf(n,t){return t="function"==typeof t?t:Q,Mr(n,an,t)}function Pf(n){return Mr(n,fn|an)}function qf(n,t){return t="function"==typeof t?t:Q,Mr(n,fn|an,t)}function Zf(n,t){return null==t||Kr(n,t,Fc(t))}function Kf(n,t){return n===t||n!==n&&t!==t}function Vf(n){return null!=n&&uc(n.length)&&!rc(n)}function Gf(n){return oc(n)&&Vf(n)}function Hf(n){return n===!0||n===!1||oc(n)&&be(n)==Mn}function Jf(n){
return oc(n)&&1===n.nodeType&&!_c(n)}function Yf(n){if(null==n)return!0;if(Vf(n)&&(yh(n)||"string"==typeof n||"function"==typeof n.splice||bh(n)||Ah(n)||gh(n)))return!n.length;var t=Is(n);if(t==Kn||t==Xn)return!n.size;if(Di(n))return!De(n).length;for(var r in n)if(yl.call(n,r))return!1;return!0}function Qf(n,t){return Ee(n,t)}function Xf(n,t,r){r="function"==typeof r?r:Q;var e=r?r(n,t):Q;return e===Q?Ee(n,t,Q,r):!!e}function nc(n){if(!oc(n))return!1;var t=be(n);return t==Pn||t==Nn||"string"==typeof n.message&&"string"==typeof n.name&&!_c(n);
}function tc(n){return"number"==typeof n&&Pl(n)}function rc(n){if(!ic(n))return!1;var t=be(n);return t==qn||t==Zn||t==Dn||t==Yn}function ec(n){return"number"==typeof n&&n==jc(n)}function uc(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=En}function ic(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function oc(n){return null!=n&&"object"==typeof n}function fc(n,t){return n===t||Le(n,t,xi(t))}function cc(n,t,r){return r="function"==typeof r?r:Q,Le(n,t,xi(t),r)}function ac(n){return pc(n)&&n!=+n;
}function lc(n){if(Rs(n))throw new il(tn);return Ce(n)}function sc(n){return null===n}function hc(n){return null==n}function pc(n){return"number"==typeof n||oc(n)&&be(n)==Vn}function _c(n){if(!oc(n)||be(n)!=Hn)return!1;var t=Rl(n);if(null===t)return!0;var r=yl.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&gl.call(r)==ml}function vc(n){return ec(n)&&n>=-En&&n<=En}function gc(n){return"string"==typeof n||!yh(n)&&oc(n)&&be(n)==nt}function yc(n){return"symbol"==typeof n||oc(n)&&be(n)==tt;
}function dc(n){return n===Q}function bc(n){return oc(n)&&Is(n)==et}function wc(n){return oc(n)&&be(n)==ut}function mc(n){if(!n)return[];if(Vf(n))return gc(n)?G(n):Bu(n);if(Ll&&n[Ll])return $(n[Ll]());var t=Is(n);return(t==Kn?D:t==Xn?P:na)(n)}function xc(n){if(!n)return 0===n?n:0;if(n=kc(n),n===zn||n===-zn){return(n<0?-1:1)*Sn}return n===n?n:0}function jc(n){var t=xc(n),r=t%1;return t===t?r?t-r:t:0}function Ac(n){return n?Dr(jc(n),0,Ln):0}function kc(n){if("number"==typeof n)return n;if(yc(n))return Wn;
if(ic(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=ic(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=n.replace(St,"");var r=Nt.test(n);return r||qt.test(n)?Yr(n.slice(2),r?2:8):Ft.test(n)?Wn:+n}function Oc(n){return Tu(n,Nc(n))}function Ic(n){return n?Dr(jc(n),-En,En):0===n?n:0}function Rc(n){return null==n?"":_u(n)}function zc(n,t){var r=_s(n);return null==t?r:Lr(r,t)}function Ec(n,t){return v(n,wi(t,3),ue)}function Sc(n,t){return v(n,wi(t,3),ie)}function Wc(n,t){return null==n?n:ys(n,wi(t,3),Nc);
}function Lc(n,t){return null==n?n:ds(n,wi(t,3),Nc)}function Cc(n,t){return n&&ue(n,wi(t,3))}function Uc(n,t){return n&&ie(n,wi(t,3))}function Bc(n){return null==n?[]:he(n,Fc(n))}function Tc(n){return null==n?[]:he(n,Nc(n))}function $c(n,t,r){var e=null==n?Q:ge(n,t);return e===Q?r:e}function Dc(n,t){return null!=n&&Ii(n,t,me)}function Mc(n,t){return null!=n&&Ii(n,t,xe)}function Fc(n){return Vf(n)?kr(n):De(n)}function Nc(n){return Vf(n)?kr(n,!0):Me(n)}function Pc(n,t){var r={};return t=wi(t,3),ue(n,function(n,e,u){
Ur(r,t(n,e,u),n)}),r}function qc(n,t){var r={};return t=wi(t,3),ue(n,function(n,e,u){Ur(r,e,t(n,e,u))}),r}function Zc(n,t){return Kc(n,Lf(wi(t)))}function Kc(n,t){if(null==n)return{};var r=c(yi(n),function(n){return[n]});return t=wi(t),Je(n,r,function(n,r){return t(n,r[0])})}function Vc(n,t,r){t=Au(t,n);var e=-1,u=t.length;for(u||(u=1,n=Q);++e<u;){var i=null==n?Q:n[Qi(t[e])];i===Q&&(e=u,i=r),n=rc(i)?i.call(n):i}return n}function Gc(n,t,r){return null==n?n:ou(n,t,r)}function Hc(n,t,r,e){return e="function"==typeof e?e:Q,
null==n?n:ou(n,t,r,e)}function Jc(n,t,e){var u=yh(n),i=u||bh(n)||Ah(n);if(t=wi(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:ic(n)&&rc(o)?_s(Rl(n)):{}}return(i?r:ue)(n,function(n,r,u){return t(e,n,r,u)}),e}function Yc(n,t){return null==n||gu(n,t)}function Qc(n,t,r){return null==n?n:yu(n,t,ju(r))}function Xc(n,t,r,e){return e="function"==typeof e?e:Q,null==n?n:yu(n,t,ju(r),e)}function na(n){return null==n?[]:z(n,Fc(n))}function ta(n){return null==n?[]:z(n,Nc(n))}function ra(n,t,r){return r===Q&&(r=t,
t=Q),r!==Q&&(r=kc(r),r=r===r?r:0),t!==Q&&(t=kc(t),t=t===t?t:0),Dr(kc(n),t,r)}function ea(n,t,r){return t=xc(t),r===Q?(r=t,t=0):r=xc(r),n=kc(n),je(n,t,r)}function ua(n,t,r){if(r&&"boolean"!=typeof r&&Ci(n,t,r)&&(t=r=Q),r===Q&&("boolean"==typeof t?(r=t,t=Q):"boolean"==typeof n&&(r=n,n=Q)),n===Q&&t===Q?(n=0,t=1):(n=xc(n),t===Q?(t=n,n=0):t=xc(t)),n>t){var e=n;n=t,t=e}if(r||n%1||t%1){var u=Jl();return Vl(n+u*(t-n+Jr("1e-"+((u+"").length-1))),t)}return nu(n,t)}function ia(n){return Jh(Rc(n).toLowerCase());
}function oa(n){return n=Rc(n),n&&n.replace(Kt,pe).replace(Tr,"")}function fa(n,t,r){n=Rc(n),t=_u(t);var e=n.length;r=r===Q?e:Dr(jc(r),0,e);var u=r;return r-=t.length,r>=0&&n.slice(r,u)==t}function ca(n){return n=Rc(n),n&&xt.test(n)?n.replace(wt,_e):n}function aa(n){return n=Rc(n),n&&Et.test(n)?n.replace(zt,"\\$&"):n}function la(n,t,r){n=Rc(n),t=jc(t);var e=t?V(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return ti(Ml(u),r)+n+ti(Dl(u),r)}function sa(n,t,r){n=Rc(n),t=jc(t);var e=t?V(n):0;return t&&e<t?n+ti(t-e,r):n;
}function ha(n,t,r){n=Rc(n),t=jc(t);var e=t?V(n):0;return t&&e<t?ti(t-e,r)+n:n}function pa(n,t,r){return r||null==t?t=0:t&&(t=+t),Hl(Rc(n).replace(Wt,""),t||0)}function _a(n,t,r){return t=(r?Ci(n,t,r):t===Q)?1:jc(t),ru(Rc(n),t)}function va(){var n=arguments,t=Rc(n[0]);return n.length<3?t:t.replace(n[1],n[2])}function ga(n,t,r){return r&&"number"!=typeof r&&Ci(n,t,r)&&(t=r=Q),(r=r===Q?Ln:r>>>0)?(n=Rc(n),n&&("string"==typeof t||null!=t&&!xh(t))&&(t=_u(t),!t&&B(n))?ku(G(n),0,r):n.split(t,r)):[]}function ya(n,t,r){
return n=Rc(n),r=null==r?0:Dr(jc(r),0,n.length),t=_u(t),n.slice(r,r+t.length)==t}function da(n,t,r){var e=Z.templateSettings;r&&Ci(n,t,r)&&(t=Q),n=Rc(n),t=zh({},t,e,ai);var u,i,o=zh({},t.imports,e.imports,ai),f=Fc(o),c=z(o,f),a=0,l=t.interpolate||Vt,s="__p += '",h=al((t.escape||Vt).source+"|"+l.source+"|"+(l===kt?Dt:Vt).source+"|"+(t.evaluate||Vt).source+"|$","g"),p="//# sourceURL="+("sourceURL"in t?t.sourceURL:"lodash.templateSources["+ ++Pr+"]")+"\n";n.replace(h,function(t,r,e,o,f,c){return e||(e=o),
s+=n.slice(a,c).replace(Gt,C),r&&(u=!0,s+="' +\n__e("+r+") +\n'"),f&&(i=!0,s+="';\n"+f+";\n__p += '"),e&&(s+="' +\n((__t = ("+e+")) == null ? '' : __t) +\n'"),a=c+t.length,t}),s+="';\n";var _=t.variable;_||(s="with (obj) {\n"+s+"\n}\n"),s=(i?s.replace(gt,""):s).replace(yt,"$1").replace(dt,"$1;"),s="function("+(_||"obj")+") {\n"+(_?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(u?", __e = _.escape":"")+(i?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+s+"return __p\n}";
var v=Yh(function(){return ol(f,p+"return "+s).apply(Q,c)});if(v.source=s,nc(v))throw v;return v}function ba(n){return Rc(n).toLowerCase()}function wa(n){return Rc(n).toUpperCase()}function ma(n,t,r){if(n=Rc(n),n&&(r||t===Q))return n.replace(St,"");if(!n||!(t=_u(t)))return n;var e=G(n),u=G(t);return ku(e,S(e,u),W(e,u)+1).join("")}function xa(n,t,r){if(n=Rc(n),n&&(r||t===Q))return n.replace(Lt,"");if(!n||!(t=_u(t)))return n;var e=G(n);return ku(e,0,W(e,G(t))+1).join("")}function ja(n,t,r){if(n=Rc(n),
n&&(r||t===Q))return n.replace(Wt,"");if(!n||!(t=_u(t)))return n;var e=G(n);return ku(e,S(e,G(t))).join("")}function Aa(n,t){var r=xn,e=jn;if(ic(t)){var u="separator"in t?t.separator:u;r="length"in t?jc(t.length):r,e="omission"in t?_u(t.omission):e}n=Rc(n);var i=n.length;if(B(n)){var o=G(n);i=o.length}if(r>=i)return n;var f=r-V(e);if(f<1)return e;var c=o?ku(o,0,f).join(""):n.slice(0,f);if(u===Q)return c+e;if(o&&(f+=c.length-f),xh(u)){if(n.slice(f).search(u)){var a,l=c;for(u.global||(u=al(u.source,Rc(Mt.exec(u))+"g")),
u.lastIndex=0;a=u.exec(l);)var s=a.index;c=c.slice(0,s===Q?f:s)}}else if(n.indexOf(_u(u),f)!=f){var h=c.lastIndexOf(u);h>-1&&(c=c.slice(0,h))}return c+e}function ka(n){return n=Rc(n),n&&mt.test(n)?n.replace(bt,ve):n}function Oa(n,t,r){return n=Rc(n),t=r?Q:t,t===Q?T(n)?Y(n):_(n):n.match(t)||[]}function Ia(t){var r=null==t?0:t.length,e=wi();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new sl(rn);return[e(n[0]),n[1]]}):[],eu(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e);
}})}function Ra(n){return Fr(Mr(n,fn))}function za(n){return function(){return n}}function Ea(n,t){return null==n||n!==n?t:n}function Sa(n){return n}function Wa(n){return $e("function"==typeof n?n:Mr(n,fn))}function La(n){return Pe(Mr(n,fn))}function Ca(n,t){return qe(n,Mr(t,fn))}function Ua(n,t,e){var u=Fc(t),i=he(t,u);null!=e||ic(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=he(t,Fc(t)));var o=!(ic(e)&&"chain"in e&&!e.chain),f=rc(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){
var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Bu(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Ba(){return ne._===this&&(ne._=xl),this}function Ta(){}function $a(n){return n=jc(n),eu(function(t){return Ve(t,n)})}function Da(n){return Ui(n)?m(Qi(n)):Ye(n)}function Ma(n){return function(t){return null==n?Q:ge(n,t)}}function Fa(){return[]}function Na(){return!1}function Pa(){return{};
}function qa(){return""}function Za(){return!0}function Ka(n,t){if(n=jc(n),n<1||n>En)return[];var r=Ln,e=Vl(n,Ln);t=wi(t),n-=Ln;for(var u=O(e,t);++r<n;)t(r);return u}function Va(n){return yh(n)?c(n,Qi):yc(n)?[n]:Bu(Ws(Rc(n)))}function Ga(n){var t=++dl;return Rc(n)+t}function Ha(n){return n&&n.length?Qr(n,Sa,we):Q}function Ja(n,t){return n&&n.length?Qr(n,wi(t,2),we):Q}function Ya(n){return w(n,Sa)}function Qa(n,t){return w(n,wi(t,2))}function Xa(n){return n&&n.length?Qr(n,Sa,Fe):Q}function nl(n,t){
return n&&n.length?Qr(n,wi(t,2),Fe):Q}function tl(n){return n&&n.length?k(n,Sa):0}function rl(n,t){return n&&n.length?k(n,wi(t,2)):0}x=null==x?ne:ye.defaults(ne.Object(),x,ye.pick(ne,Nr));var el=x.Array,ul=x.Date,il=x.Error,ol=x.Function,fl=x.Math,cl=x.Object,al=x.RegExp,ll=x.String,sl=x.TypeError,hl=el.prototype,pl=ol.prototype,_l=cl.prototype,vl=x["__core-js_shared__"],gl=pl.toString,yl=_l.hasOwnProperty,dl=0,bl=function(){var n=/[^.]+$/.exec(vl&&vl.keys&&vl.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:"";
}(),wl=_l.toString,ml=gl.call(cl),xl=ne._,jl=al("^"+gl.call(yl).replace(zt,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Al=ee?x.Buffer:Q,kl=x.Symbol,Ol=x.Uint8Array,Il=Al?Al.allocUnsafe:Q,Rl=M(cl.getPrototypeOf,cl),zl=cl.create,El=_l.propertyIsEnumerable,Sl=hl.splice,Wl=kl?kl.isConcatSpreadable:Q,Ll=kl?kl.iterator:Q,Cl=kl?kl.toStringTag:Q,Ul=function(){try{var n=ji(cl,"defineProperty");return n({},"",{}),n}catch(n){}}(),Bl=x.clearTimeout!==ne.clearTimeout&&x.clearTimeout,Tl=ul&&ul.now!==ne.Date.now&&ul.now,$l=x.setTimeout!==ne.setTimeout&&x.setTimeout,Dl=fl.ceil,Ml=fl.floor,Fl=cl.getOwnPropertySymbols,Nl=Al?Al.isBuffer:Q,Pl=x.isFinite,ql=hl.join,Zl=M(cl.keys,cl),Kl=fl.max,Vl=fl.min,Gl=ul.now,Hl=x.parseInt,Jl=fl.random,Yl=hl.reverse,Ql=ji(x,"DataView"),Xl=ji(x,"Map"),ns=ji(x,"Promise"),ts=ji(x,"Set"),rs=ji(x,"WeakMap"),es=ji(cl,"create"),us=rs&&new rs,is={},os=Xi(Ql),fs=Xi(Xl),cs=Xi(ns),as=Xi(ts),ls=Xi(rs),ss=kl?kl.prototype:Q,hs=ss?ss.valueOf:Q,ps=ss?ss.toString:Q,_s=function(){
function n(){}return function(t){if(!ic(t))return{};if(zl)return zl(t);n.prototype=t;var r=new n;return n.prototype=Q,r}}();Z.templateSettings={escape:jt,evaluate:At,interpolate:kt,variable:"",imports:{_:Z}},Z.prototype=H.prototype,Z.prototype.constructor=Z,J.prototype=_s(H.prototype),J.prototype.constructor=J,Tt.prototype=_s(H.prototype),Tt.prototype.constructor=Tt,Qt.prototype.clear=Xt,Qt.prototype.delete=nr,Qt.prototype.get=tr,Qt.prototype.has=rr,Qt.prototype.set=er,ur.prototype.clear=ir,ur.prototype.delete=or,
ur.prototype.get=fr,ur.prototype.has=cr,ur.prototype.set=ar,lr.prototype.clear=sr,lr.prototype.delete=hr,lr.prototype.get=pr,lr.prototype.has=_r,lr.prototype.set=vr,gr.prototype.add=gr.prototype.push=yr,gr.prototype.has=dr,br.prototype.clear=wr,br.prototype.delete=mr,br.prototype.get=xr,br.prototype.has=jr,br.prototype.set=Ar;var vs=Nu(ue),gs=Nu(ie,!0),ys=Pu(),ds=Pu(!0),bs=us?function(n,t){return us.set(n,t),n}:Sa,ws=Ul?function(n,t){return Ul(n,"toString",{configurable:!0,enumerable:!1,value:za(t),
writable:!0})}:Sa,ms=eu,xs=Bl||function(n){return ne.clearTimeout(n)},js=ts&&1/P(new ts([,-0]))[1]==zn?function(n){return new ts(n)}:Ta,As=us?function(n){return us.get(n)}:Ta,ks=Fl?function(n){return null==n?[]:(n=cl(n),i(Fl(n),function(t){return El.call(n,t)}))}:Fa,Os=Fl?function(n){for(var t=[];n;)a(t,ks(n)),n=Rl(n);return t}:Fa,Is=be;(Ql&&Is(new Ql(new ArrayBuffer(1)))!=ot||Xl&&Is(new Xl)!=Kn||ns&&Is(ns.resolve())!=Jn||ts&&Is(new ts)!=Xn||rs&&Is(new rs)!=et)&&(Is=function(n){var t=be(n),r=t==Hn?n.constructor:Q,e=r?Xi(r):"";
if(e)switch(e){case os:return ot;case fs:return Kn;case cs:return Jn;case as:return Xn;case ls:return et}return t});var Rs=vl?rc:Na,zs=Ji(bs),Es=$l||function(n,t){return ne.setTimeout(n,t)},Ss=Ji(ws),Ws=Ni(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(Rt,function(n,r,e,u){t.push(e?u.replace($t,"$1"):r||n)}),t}),Ls=eu(function(n,t){return Gf(n)?Gr(n,re(t,1,Gf,!0)):[]}),Cs=eu(function(n,t){var r=mo(t);return Gf(r)&&(r=Q),Gf(n)?Gr(n,re(t,1,Gf,!0),wi(r,2)):[]}),Us=eu(function(n,t){
var r=mo(t);return Gf(r)&&(r=Q),Gf(n)?Gr(n,re(t,1,Gf,!0),Q,r):[]}),Bs=eu(function(n){var t=c(n,xu);return t.length&&t[0]===n[0]?Ae(t):[]}),Ts=eu(function(n){var t=mo(n),r=c(n,xu);return t===mo(r)?t=Q:r.pop(),r.length&&r[0]===n[0]?Ae(r,wi(t,2)):[]}),$s=eu(function(n){var t=mo(n),r=c(n,xu);return t="function"==typeof t?t:Q,t&&r.pop(),r.length&&r[0]===n[0]?Ae(r,Q,t):[]}),Ds=eu(Ao),Ms=vi(function(n,t){var r=null==n?0:n.length,e=$r(n,t);return Xe(n,c(t,function(n){return Li(n,r)?+n:n}).sort(Wu)),e}),Fs=eu(function(n){
return vu(re(n,1,Gf,!0))}),Ns=eu(function(n){var t=mo(n);return Gf(t)&&(t=Q),vu(re(n,1,Gf,!0),wi(t,2))}),Ps=eu(function(n){var t=mo(n);return t="function"==typeof t?t:Q,vu(re(n,1,Gf,!0),Q,t)}),qs=eu(function(n,t){return Gf(n)?Gr(n,t):[]}),Zs=eu(function(n){return wu(i(n,Gf))}),Ks=eu(function(n){var t=mo(n);return Gf(t)&&(t=Q),wu(i(n,Gf),wi(t,2))}),Vs=eu(function(n){var t=mo(n);return t="function"==typeof t?t:Q,wu(i(n,Gf),Q,t)}),Gs=eu(Ko),Hs=eu(function(n){var t=n.length,r=t>1?n[t-1]:Q;return r="function"==typeof r?(n.pop(),
r):Q,Vo(n,r)}),Js=vi(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return $r(t,n)};return!(t>1||this.__actions__.length)&&e instanceof Tt&&Li(r)?(e=e.slice(r,+r+(t?1:0)),e.__actions__.push({func:Qo,args:[u],thisArg:Q}),new J(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(Q),n})):this.thru(u)}),Ys=Mu(function(n,t,r){yl.call(n,r)?++n[r]:Ur(n,r,1)}),Qs=Hu(lo),Xs=Hu(so),nh=Mu(function(n,t,r){yl.call(n,r)?n[r].push(t):Ur(n,r,[t])}),th=eu(function(t,r,e){var u=-1,i="function"==typeof r,o=Vf(t)?el(t.length):[];
return vs(t,function(t){o[++u]=i?n(r,t,e):Oe(t,r,e)}),o}),rh=Mu(function(n,t,r){Ur(n,r,t)}),eh=Mu(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),uh=eu(function(n,t){if(null==n)return[];var r=t.length;return r>1&&Ci(n,t[0],t[1])?t=[]:r>2&&Ci(t[0],t[1],t[2])&&(t=[t[0]]),Ge(n,re(t,1),[])}),ih=Tl||function(){return ne.Date.now()},oh=eu(function(n,t,r){var e=hn;if(r.length){var u=F(r,bi(oh));e|=yn}return ci(n,e,t,r,u)}),fh=eu(function(n,t,r){var e=hn|pn;if(r.length){var u=F(r,bi(fh));e|=yn;
}return ci(t,e,n,r,u)}),ch=eu(function(n,t){return Vr(n,1,t)}),ah=eu(function(n,t,r){return Vr(n,kc(t)||0,r)});Wf.Cache=lr;var lh=ms(function(t,r){r=1==r.length&&yh(r[0])?c(r[0],R(wi())):c(re(r,1),R(wi()));var e=r.length;return eu(function(u){for(var i=-1,o=Vl(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);return n(t,this,u)})}),sh=eu(function(n,t){return ci(n,yn,Q,t,F(t,bi(sh)))}),hh=eu(function(n,t){return ci(n,dn,Q,t,F(t,bi(hh)))}),ph=vi(function(n,t){return ci(n,wn,Q,Q,Q,t)}),_h=ui(we),vh=ui(function(n,t){
return n>=t}),gh=Ie(function(){return arguments}())?Ie:function(n){return oc(n)&&yl.call(n,"callee")&&!El.call(n,"callee")},yh=el.isArray,dh=oe?R(oe):Re,bh=Nl||Na,wh=fe?R(fe):ze,mh=ce?R(ce):We,xh=ae?R(ae):Ue,jh=le?R(le):Be,Ah=se?R(se):Te,kh=ui(Fe),Oh=ui(function(n,t){return n<=t}),Ih=Fu(function(n,t){if(Di(t)||Vf(t))return Tu(t,Fc(t),n),Q;for(var r in t)yl.call(t,r)&&Er(n,r,t[r])}),Rh=Fu(function(n,t){Tu(t,Nc(t),n)}),zh=Fu(function(n,t,r,e){Tu(t,Nc(t),n,e)}),Eh=Fu(function(n,t,r,e){Tu(t,Fc(t),n,e);
}),Sh=vi($r),Wh=eu(function(n,t){n=cl(n);var r=-1,e=t.length,u=e>2?t[2]:Q;for(u&&Ci(t[0],t[1],u)&&(e=1);++r<e;)for(var i=t[r],o=Nc(i),f=-1,c=o.length;++f<c;){var a=o[f],l=n[a];(l===Q||Kf(l,_l[a])&&!yl.call(n,a))&&(n[a]=i[a])}return n}),Lh=eu(function(t){return t.push(Q,li),n($h,Q,t)}),Ch=Qu(function(n,t,r){null!=t&&"function"!=typeof t.toString&&(t=wl.call(t)),n[t]=r},za(Sa)),Uh=Qu(function(n,t,r){null!=t&&"function"!=typeof t.toString&&(t=wl.call(t)),yl.call(n,t)?n[t].push(r):n[t]=[r]},wi),Bh=eu(Oe),Th=Fu(function(n,t,r){
Ze(n,t,r)}),$h=Fu(function(n,t,r,e){Ze(n,t,r,e)}),Dh=vi(function(n,t){var r={};if(null==n)return r;var e=!1;t=c(t,function(t){return t=Au(t,n),e||(e=t.length>1),t}),Tu(n,yi(n),r),e&&(r=Mr(r,fn|cn|an,si));for(var u=t.length;u--;)gu(r,t[u]);return r}),Mh=vi(function(n,t){return null==n?{}:He(n,t)}),Fh=fi(Fc),Nh=fi(Nc),Ph=Ku(function(n,t,r){return t=t.toLowerCase(),n+(r?ia(t):t)}),qh=Ku(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Zh=Ku(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Kh=Zu("toLowerCase"),Vh=Ku(function(n,t,r){
return n+(r?"_":"")+t.toLowerCase()}),Gh=Ku(function(n,t,r){return n+(r?" ":"")+Jh(t)}),Hh=Ku(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Jh=Zu("toUpperCase"),Yh=eu(function(t,r){try{return n(t,Q,r)}catch(n){return nc(n)?n:new il(n)}}),Qh=vi(function(n,t){return r(t,function(t){t=Qi(t),Ur(n,t,oh(n[t],n))}),n}),Xh=Ju(),np=Ju(!0),tp=eu(function(n,t){return function(r){return Oe(r,n,t)}}),rp=eu(function(n,t){return function(r){return Oe(n,r,t)}}),ep=ni(c),up=ni(u),ip=ni(h),op=ei(),fp=ei(!0),cp=Xu(function(n,t){
return n+t},0),ap=oi("ceil"),lp=Xu(function(n,t){return n/t},1),sp=oi("floor"),hp=Xu(function(n,t){return n*t},1),pp=oi("round"),_p=Xu(function(n,t){return n-t},0);return Z.after=kf,Z.ary=Of,Z.assign=Ih,Z.assignIn=Rh,Z.assignInWith=zh,Z.assignWith=Eh,Z.at=Sh,Z.before=If,Z.bind=oh,Z.bindAll=Qh,Z.bindKey=fh,Z.castArray=Mf,Z.chain=Jo,Z.chunk=ro,Z.compact=eo,Z.concat=uo,Z.cond=Ia,Z.conforms=Ra,Z.constant=za,Z.countBy=Ys,Z.create=zc,Z.curry=Rf,Z.curryRight=zf,Z.debounce=Ef,Z.defaults=Wh,Z.defaultsDeep=Lh,
Z.defer=ch,Z.delay=ah,Z.difference=Ls,Z.differenceBy=Cs,Z.differenceWith=Us,Z.drop=io,Z.dropRight=oo,Z.dropRightWhile=fo,Z.dropWhile=co,Z.fill=ao,Z.filter=cf,Z.flatMap=af,Z.flatMapDeep=lf,Z.flatMapDepth=sf,Z.flatten=ho,Z.flattenDeep=po,Z.flattenDepth=_o,Z.flip=Sf,Z.flow=Xh,Z.flowRight=np,Z.fromPairs=vo,Z.functions=Bc,Z.functionsIn=Tc,Z.groupBy=nh,Z.initial=bo,Z.intersection=Bs,Z.intersectionBy=Ts,Z.intersectionWith=$s,Z.invert=Ch,Z.invertBy=Uh,Z.invokeMap=th,Z.iteratee=Wa,Z.keyBy=rh,Z.keys=Fc,Z.keysIn=Nc,
Z.map=vf,Z.mapKeys=Pc,Z.mapValues=qc,Z.matches=La,Z.matchesProperty=Ca,Z.memoize=Wf,Z.merge=Th,Z.mergeWith=$h,Z.method=tp,Z.methodOf=rp,Z.mixin=Ua,Z.negate=Lf,Z.nthArg=$a,Z.omit=Dh,Z.omitBy=Zc,Z.once=Cf,Z.orderBy=gf,Z.over=ep,Z.overArgs=lh,Z.overEvery=up,Z.overSome=ip,Z.partial=sh,Z.partialRight=hh,Z.partition=eh,Z.pick=Mh,Z.pickBy=Kc,Z.property=Da,Z.propertyOf=Ma,Z.pull=Ds,Z.pullAll=Ao,Z.pullAllBy=ko,Z.pullAllWith=Oo,Z.pullAt=Ms,Z.range=op,Z.rangeRight=fp,Z.rearg=ph,Z.reject=bf,Z.remove=Io,Z.rest=Uf,
Z.reverse=Ro,Z.sampleSize=mf,Z.set=Gc,Z.setWith=Hc,Z.shuffle=xf,Z.slice=zo,Z.sortBy=uh,Z.sortedUniq=Bo,Z.sortedUniqBy=To,Z.split=ga,Z.spread=Bf,Z.tail=$o,Z.take=Do,Z.takeRight=Mo,Z.takeRightWhile=Fo,Z.takeWhile=No,Z.tap=Yo,Z.throttle=Tf,Z.thru=Qo,Z.toArray=mc,Z.toPairs=Fh,Z.toPairsIn=Nh,Z.toPath=Va,Z.toPlainObject=Oc,Z.transform=Jc,Z.unary=$f,Z.union=Fs,Z.unionBy=Ns,Z.unionWith=Ps,Z.uniq=Po,Z.uniqBy=qo,Z.uniqWith=Zo,Z.unset=Yc,Z.unzip=Ko,Z.unzipWith=Vo,Z.update=Qc,Z.updateWith=Xc,Z.values=na,Z.valuesIn=ta,
Z.without=qs,Z.words=Oa,Z.wrap=Df,Z.xor=Zs,Z.xorBy=Ks,Z.xorWith=Vs,Z.zip=Gs,Z.zipObject=Go,Z.zipObjectDeep=Ho,Z.zipWith=Hs,Z.entries=Fh,Z.entriesIn=Nh,Z.extend=Rh,Z.extendWith=zh,Ua(Z,Z),Z.add=cp,Z.attempt=Yh,Z.camelCase=Ph,Z.capitalize=ia,Z.ceil=ap,Z.clamp=ra,Z.clone=Ff,Z.cloneDeep=Pf,Z.cloneDeepWith=qf,Z.cloneWith=Nf,Z.conformsTo=Zf,Z.deburr=oa,Z.defaultTo=Ea,Z.divide=lp,Z.endsWith=fa,Z.eq=Kf,Z.escape=ca,Z.escapeRegExp=aa,Z.every=ff,Z.find=Qs,Z.findIndex=lo,Z.findKey=Ec,Z.findLast=Xs,Z.findLastIndex=so,
Z.findLastKey=Sc,Z.floor=sp,Z.forEach=hf,Z.forEachRight=pf,Z.forIn=Wc,Z.forInRight=Lc,Z.forOwn=Cc,Z.forOwnRight=Uc,Z.get=$c,Z.gt=_h,Z.gte=vh,Z.has=Dc,Z.hasIn=Mc,Z.head=go,Z.identity=Sa,Z.includes=_f,Z.indexOf=yo,Z.inRange=ea,Z.invoke=Bh,Z.isArguments=gh,Z.isArray=yh,Z.isArrayBuffer=dh,Z.isArrayLike=Vf,Z.isArrayLikeObject=Gf,Z.isBoolean=Hf,Z.isBuffer=bh,Z.isDate=wh,Z.isElement=Jf,Z.isEmpty=Yf,Z.isEqual=Qf,Z.isEqualWith=Xf,Z.isError=nc,Z.isFinite=tc,Z.isFunction=rc,Z.isInteger=ec,Z.isLength=uc,Z.isMap=mh,
Z.isMatch=fc,Z.isMatchWith=cc,Z.isNaN=ac,Z.isNative=lc,Z.isNil=hc,Z.isNull=sc,Z.isNumber=pc,Z.isObject=ic,Z.isObjectLike=oc,Z.isPlainObject=_c,Z.isRegExp=xh,Z.isSafeInteger=vc,Z.isSet=jh,Z.isString=gc,Z.isSymbol=yc,Z.isTypedArray=Ah,Z.isUndefined=dc,Z.isWeakMap=bc,Z.isWeakSet=wc,Z.join=wo,Z.kebabCase=qh,Z.last=mo,Z.lastIndexOf=xo,Z.lowerCase=Zh,Z.lowerFirst=Kh,Z.lt=kh,Z.lte=Oh,Z.max=Ha,Z.maxBy=Ja,Z.mean=Ya,Z.meanBy=Qa,Z.min=Xa,Z.minBy=nl,Z.stubArray=Fa,Z.stubFalse=Na,Z.stubObject=Pa,Z.stubString=qa,
Z.stubTrue=Za,Z.multiply=hp,Z.nth=jo,Z.noConflict=Ba,Z.noop=Ta,Z.now=ih,Z.pad=la,Z.padEnd=sa,Z.padStart=ha,Z.parseInt=pa,Z.random=ua,Z.reduce=yf,Z.reduceRight=df,Z.repeat=_a,Z.replace=va,Z.result=Vc,Z.round=pp,Z.runInContext=p,Z.sample=wf,Z.size=jf,Z.snakeCase=Vh,Z.some=Af,Z.sortedIndex=Eo,Z.sortedIndexBy=So,Z.sortedIndexOf=Wo,Z.sortedLastIndex=Lo,Z.sortedLastIndexBy=Co,Z.sortedLastIndexOf=Uo,Z.startCase=Gh,Z.startsWith=ya,Z.subtract=_p,Z.sum=tl,Z.sumBy=rl,Z.template=da,Z.times=Ka,Z.toFinite=xc,Z.toInteger=jc,
Z.toLength=Ac,Z.toLower=ba,Z.toNumber=kc,Z.toSafeInteger=Ic,Z.toString=Rc,Z.toUpper=wa,Z.trim=ma,Z.trimEnd=xa,Z.trimStart=ja,Z.truncate=Aa,Z.unescape=ka,Z.uniqueId=Ga,Z.upperCase=Hh,Z.upperFirst=Jh,Z.each=hf,Z.eachRight=pf,Z.first=go,Ua(Z,function(){var n={};return ue(Z,function(t,r){yl.call(Z.prototype,r)||(n[r]=t)}),n}(),{chain:!1}),Z.VERSION=X,r(["bind","bindKey","curry","curryRight","partial","partialRight"],function(n){Z[n].placeholder=Z}),r(["drop","take"],function(n,t){Tt.prototype[n]=function(r){
r=r===Q?1:Kl(jc(r),0);var e=this.__filtered__&&!t?new Tt(this):this.clone();return e.__filtered__?e.__takeCount__=Vl(r,e.__takeCount__):e.__views__.push({size:Vl(r,Ln),type:n+(e.__dir__<0?"Right":"")}),e},Tt.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=r==On||r==Rn;Tt.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:wi(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){
var r="take"+(t?"Right":"");Tt.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Tt.prototype[n]=function(){return this.__filtered__?new Tt(this):this[r](1)}}),Tt.prototype.compact=function(){return this.filter(Sa)},Tt.prototype.find=function(n){return this.filter(n).head()},Tt.prototype.findLast=function(n){return this.reverse().find(n)},Tt.prototype.invokeMap=eu(function(n,t){return"function"==typeof n?new Tt(this):this.map(function(r){
return Oe(r,n,t)})}),Tt.prototype.reject=function(n){return this.filter(Lf(wi(n)))},Tt.prototype.slice=function(n,t){n=jc(n);var r=this;return r.__filtered__&&(n>0||t<0)?new Tt(r):(n<0?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==Q&&(t=jc(t),r=t<0?r.dropRight(-t):r.take(t-n)),r)},Tt.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Tt.prototype.toArray=function(){return this.take(Ln)},ue(Tt.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=Z[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);
u&&(Z.prototype[t]=function(){var t=this.__wrapped__,o=e?[1]:arguments,f=t instanceof Tt,c=o[0],l=f||yh(t),s=function(n){var t=u.apply(Z,a([n],o));return e&&h?t[0]:t};l&&r&&"function"==typeof c&&1!=c.length&&(f=l=!1);var h=this.__chain__,p=!!this.__actions__.length,_=i&&!h,v=f&&!p;if(!i&&l){t=v?t:new Tt(this);var g=n.apply(t,o);return g.__actions__.push({func:Qo,args:[s],thisArg:Q}),new J(g,h)}return _&&v?n.apply(this,o):(g=this.thru(s),_?e?g.value()[0]:g.value():g)})}),r(["pop","push","shift","sort","splice","unshift"],function(n){
var t=hl[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);Z.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(yh(u)?u:[],n)}return this[r](function(r){return t.apply(yh(r)?r:[],n)})}}),ue(Tt.prototype,function(n,t){var r=Z[t];if(r){var e=r.name+"";(is[e]||(is[e]=[])).push({name:t,func:r})}}),is[Yu(Q,pn).name]=[{name:"wrapper",func:Q}],Tt.prototype.clone=Ht,Tt.prototype.reverse=Jt,Tt.prototype.value=Yt,Z.prototype.at=Js,
Z.prototype.chain=Xo,Z.prototype.commit=nf,Z.prototype.next=tf,Z.prototype.plant=ef,Z.prototype.reverse=uf,Z.prototype.toJSON=Z.prototype.valueOf=Z.prototype.value=of,Z.prototype.first=Z.prototype.head,Ll&&(Z.prototype[Ll]=rf),Z},ye=ge();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(ne._=ye,define(function(){return ye})):re?((re.exports=ye)._=ye,te._=ye):ne._=ye}).call(this);

4
dolphinscheduler-ui/src/3rdjs/python.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/shell.min.js vendored

@ -1,4 +0,0 @@
/*
* Licensed MIT
*/
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(i){"use strict";i.defineMode("shell",function(){var o={};function e(e,t){for(var n=0;n<t.length;n++)o[t[n]]=e}var t=["true","false"],n=["if","then","do","else","elif","while","until","for","in","esac","fi","fin","fil","done","exit","set","unset","export","function"],r=["ab","awk","bash","beep","cat","cc","cd","chown","chmod","chroot","clear","cp","curl","cut","diff","echo","find","gawk","gcc","get","git","grep","hg","kill","killall","ln","ls","make","mkdir","openssl","mv","nc","nl","node","npm","ping","ps","restart","rm","rmdir","sed","service","sh","shopt","shred","source","sort","sleep","ssh","start","stop","su","sudo","svn","tee","telnet","top","touch","vi","vim","wall","wc","wget","who","write","yes","zsh"];function u(i,o){var s="("==i?")":"{"==i?"}":i;return function(e,t){for(var n,r=!1;null!=(n=e.next());){if(n===s&&!r){t.tokens.shift();break}if("$"===n&&!r&&"'"!==i&&e.peek()!=s){r=!0,e.backUp(1),t.tokens.unshift(l);break}if(!r&&i!==s&&n===i)return t.tokens.unshift(u(i,o)),c(e,t);if(!r&&/['"]/.test(n)&&!/['"]/.test(i)){t.tokens.unshift(f(n,"string")),e.backUp(1);break}r=!r&&"\\"===n}return o}}function f(n,r){return function(e,t){return t.tokens[0]=u(n,r),e.next(),c(e,t)}}i.registerHelper("hintWords","shell",t.concat(n,r)),e("atom",t),e("keyword",n),e("builtin",r);var l=function(e,t){1<t.tokens.length&&e.eat("$");var n=e.next();return/['"({]/.test(n)?(t.tokens[0]=u(n,"("==n?"quote":"{"==n?"def":"string"),c(e,t)):(/\d/.test(n)||e.eatWhile(/\w/),t.tokens.shift(),"def")};function c(e,t){return(t.tokens[0]||function(e,t){if(e.eatSpace())return null;var n=e.sol(),r=e.next();if("\\"===r)return e.next(),null;if("'"===r||'"'===r||"`"===r)return t.tokens.unshift(u(r,"`"===r?"quote":"string")),c(e,t);if("#"===r)return n&&e.eat("!")?(e.skipToEnd(),"meta"):(e.skipToEnd(),"comment");if("$"===r)return t.tokens.unshift(l),c(e,t);if("+"===r||"="===r)return"operator";if("-"===r)return e.eat("-"),e.eatWhile(/\w/),"attribute";if(/\d/.test(r)&&(e.eatWhile(/\d/),e.eol()||!/\w/.test(e.peek())))return"number";e.eatWhile(/[\w-]/);var i=e.current();return"="===e.peek()&&/\w+/.test(i)?"def":o.hasOwnProperty(i)?o[i]:null})(e,t)}return{startState:function(){return{tokens:[]}},token:function(e,t){return c(e,t)},closeBrackets:"()[]{}''\"\"``",lineComment:"#",fold:"brace"}}),i.defineMIME("text/x-sh","shell"),i.defineMIME("application/x-sh","shell")});

4
dolphinscheduler-ui/src/3rdjs/show-hint.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/sql-hint.min.js vendored

@ -1,4 +0,0 @@
/*
* Licensed MIT
*/
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("../../mode/sql/sql")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../../mode/sql/sql"],t):t(CodeMirror)}(function(p){"use strict";var g,h,d,v,x={QUERY_DIV:";",ALIAS_KEYWORD:"AS"},m=p.Pos,b=p.cmpPos;function y(t){return"[object Array]"==Object.prototype.toString.call(t)}function C(t){return"string"==typeof t?t:t.text}function A(t,e){return y(e)&&(e={columns:e}),e.text||(e.text=t),e}function q(t){return g[t.toUpperCase()]}function U(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function a(t,e){var r=t.length,n=C(e).substr(0,r);return t.toUpperCase()===n.toUpperCase()}function j(t,e,r,n){if(y(r))for(var o=0;o<r.length;o++)a(e,r[o])&&t.push(n(r[o]));else for(var i in r)if(r.hasOwnProperty(i)){var s=r[i];a(e,s=s&&!0!==s?s.displayText?{text:s.text,displayText:s.displayText}:s.text:i)&&t.push(n(s))}}function w(t){"."==t.charAt(0)&&(t=t.substr(1));for(var e=t.split(v+v),r=0;r<e.length;r++)e[r]=e[r].replace(new RegExp(v,"g"),"");return e.join(v)}function O(t){for(var e=C(t).split("."),r=0;r<e.length;r++)e[r]=v+e[r].replace(new RegExp(v,"g"),v+v)+v;var n=e.join(".");return"string"==typeof t?n:((t=U(t)).text=n,t)}function L(t,e){for(var r=t.split(/\s+/),n=0;n<r.length;n++)r[n]&&e(r[n].replace(/[,;]/g,""))}function M(t,e){for(var r=e.doc,n=r.getValue(),o=t.toUpperCase(),i="",s="",a=[],l={start:m(0,0),end:m(e.lastLine(),e.getLineHandle(e.lastLine()).length)},u=n.indexOf(x.QUERY_DIV);-1!=u;)a.push(r.posFromIndex(u)),u=n.indexOf(x.QUERY_DIV,u+1);a.unshift(m(0,0)),a.push(m(e.lastLine(),e.getLineHandle(e.lastLine()).text.length));for(var f=null,c=e.getCursor(),p=0;p<a.length;p++){if((null==f||0<b(c,f))&&b(c,a[p])<=0){l={start:f,end:a[p]};break}f=a[p]}if(l.start){var d=r.getRange(l.start,l.end,!1);for(p=0;p<d.length;p++){if(L(d[p],function(t){var e=t.toUpperCase();e===o&&q(i)&&(s=i),e!==x.ALIAS_KEYWORD&&(i=t)}),s)break}}return s}p.registerHelper("hint","sql",function(t,e){g=function(t){var e={};if(y(t))for(var r=t.length-1;0<=r;r--){var n=t[r];e[C(n).toUpperCase()]=A(C(n),n)}else if(t)for(var o in t)e[o.toUpperCase()]=A(o,t[o]);return e}(e&&e.tables);var r,n,o=e&&e.defaultTable,i=e&&e.disableKeywords;h=o&&q(o),"sql"===(r=t.doc.modeOption)&&(r="text/x-sql"),d=p.resolveMode(r).keywords,"sql"===(n=t.doc.modeOption)&&(n="text/x-sql"),v=p.resolveMode(n).identifierQuote||"`",o&&!h&&(h=M(o,t)),(h=h||[]).columns&&(h=h.columns);var s,a,l,u=t.getCursor(),f=[],c=t.getTokenAt(u);return c.end>u.ch&&(c.end=u.ch,c.string=c.string.slice(0,u.ch-c.start)),c.string.match(/^[.`"\w@]\w*$/)?(l=c.string,s=c.start,a=c.end):(s=a=u.ch,l=""),"."==l.charAt(0)||l.charAt(0)==v?s=function(t,e,r,n){for(var o=!1,i=[],s=e.start,a=!0;a;)a="."==e.string.charAt(0),o=o||e.string.charAt(0)==v,s=e.start,i.unshift(w(e.string)),"."==(e=n.getTokenAt(m(t.line,e.start))).string&&(a=!0,e=n.getTokenAt(m(t.line,e.start)));var l=i.join(".");j(r,l,g,function(t){return o?O(t):t}),j(r,l,h,function(t){return o?O(t):t}),l=i.pop();var u=i.join("."),f=!1,c=u;if(!q(u)){var p=u;(u=M(u,n))!==p&&(f=!0)}var d=q(u);return d&&d.columns&&(d=d.columns),d&&j(r,l,d,function(t){var e=u;return 1==f&&(e=c),"string"==typeof t?t=e+"."+t:(t=U(t)).text=e+"."+t.text,o?O(t):t}),s}(u,c,f,t):(j(f,l,h,function(t){return{text:t,className:"CodeMirror-hint-table CodeMirror-hint-default-table"}}),j(f,l,g,function(t){return"object"==typeof t?t.className="CodeMirror-hint-table":t={text:t,className:"CodeMirror-hint-table"},t}),i||j(f,l,d,function(t){return{text:t.toUpperCase(),className:"CodeMirror-hint-keyword"}})),{list:f,from:m(u.line,s),to:m(u.line,a)}})});

4
dolphinscheduler-ui/src/3rdjs/sql.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/textile.min.js vendored

File diff suppressed because one or more lines are too long

6
dolphinscheduler-ui/src/3rdjs/vue-router.min.js vendored

File diff suppressed because one or more lines are too long

10552
dolphinscheduler-ui/src/3rdjs/vue.js

File diff suppressed because it is too large Load Diff

6
dolphinscheduler-ui/src/3rdjs/vuex.min.js vendored

File diff suppressed because one or more lines are too long

4
dolphinscheduler-ui/src/3rdjs/xml-hint.min.js vendored

@ -1,4 +0,0 @@
/*
* Licensed MIT
*/
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}(function(C){"use strict";var j=C.Pos;C.registerHelper("hint","xml",function(t,e){var r=e&&e.schemaInfo,s=e&&e.quoteChar||'"';if(r){var n=t.getCursor(),a=t.getTokenAt(n);a.end>n.ch&&(a.end=n.ch,a.string=a.string.slice(0,n.ch-a.start));var i=C.innerMode(t.getMode(),a.state);if("xml"==i.mode.name){var o,l,f=[],g=!1,c=/\btag\b/.test(a.type)&&!/>$/.test(a.string),h=c&&/^\w/.test(a.string);if(h){var p=t.getLine(n.line).slice(Math.max(0,a.start-2),a.start),u=/<\/$/.test(p)?"close":/<$/.test(p)?"open":null;u&&(l=a.start-("close"==u?2:1))}else c&&"<"==a.string?u="open":c&&"</"==a.string&&(u="close");if(!c&&!i.state.tagName||u){h&&(o=a.string),g=u;var d=i.state.context,m=d&&r[d.tagName],v=d?m&&m.children:r["!top"];if(v&&"close"!=u)for(var y=0;y<v.length;++y)o&&0!=v[y].lastIndexOf(o,0)||f.push("<"+v[y]);else if("close"!=u)for(var x in r)!r.hasOwnProperty(x)||"!top"==x||"!attrs"==x||o&&0!=x.lastIndexOf(o,0)||f.push("<"+x);d&&(!o||"close"==u&&0==d.tagName.lastIndexOf(o,0))&&f.push("</"+d.tagName+">")}else{var O=(m=r[i.state.tagName])&&m.attrs,b=r["!attrs"];if(!O&&!b)return;if(O){if(b){var w={};for(var I in b)b.hasOwnProperty(I)&&(w[I]=b[I]);for(var I in O)O.hasOwnProperty(I)&&(w[I]=O[I]);O=w}}else O=b;if("string"==a.type||"="==a.string){var P,A=(p=t.getRange(j(n.line,Math.max(0,n.ch-60)),j(n.line,"string"==a.type?a.start:a.end))).match(/([^\s\u00a0=<>\"\']+)=$/);if(!A||!O.hasOwnProperty(A[1])||!(P=O[A[1]]))return;if("function"==typeof P&&(P=P.call(this,t)),"string"==a.type){o=a.string;var M=0;/['"]/.test(a.string.charAt(0))&&(s=a.string.charAt(0),o=a.string.slice(1),M++);var N=a.string.length;/['"]/.test(a.string.charAt(N-1))&&(s=a.string.charAt(N-1),o=a.string.substr(M,N-2)),g=!0}for(y=0;y<P.length;++y)o&&0!=P[y].lastIndexOf(o,0)||f.push(s+P[y]+s)}else for(var $ in"attribute"==a.type&&(o=a.string,g=!0),O)!O.hasOwnProperty($)||o&&0!=$.lastIndexOf(o,0)||f.push($)}return{list:f,from:g?j(n.line,null==l?a.start:l):n,to:g?j(n.line,a.end):n}}}})});

4
dolphinscheduler-ui/src/3rdjs/xml.min.js vendored

File diff suppressed because one or more lines are too long

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

@ -17,7 +17,7 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import $ from 'jquery'
// import $ from 'jquery'
import Vue from 'vue'
import App from './App'
import router from './router'
@ -32,6 +32,10 @@ import 'ans-ui/lib/ans-ui.min.css'
import ans from 'ans-ui/lib/ans-ui.min'
import en_US from 'ans-ui/lib/locale/en' // eslint-disable-line
import 'sass/conf/home/index.scss'
import'bootstrap/dist/css/bootstrap.min.css'
import'bootstrap/dist/js/bootstrap.min.js'
import 'canvg/dist/browser/canvg.min.js'
// Component internationalization
let useOpt = i18n.globalScope.LOCALE === 'en_US' ? { locale: en_US } : {}

2
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/timeoutAlarm.vue

@ -49,7 +49,7 @@
</div>
<div class="cont-box">
<label class="label-box">
<x-input v-model="interval" style="width: 128px;" :disabled="isDetails" maxlength="9">
<x-input v-model="interval" style="width: 200px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</x-input>
</label>

4
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/http.vue

@ -101,7 +101,7 @@
<script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import cookie from '@/module/util/cookie'
import cookies from 'js-cookie'
import mLocalParams from './_source/localParams'
import mHttpParams from './_source/httpParams'
import mListBox from './_source/listBox'
@ -117,7 +117,7 @@
httpMethod: 'GET',
httpMethodList: [{ code: 'GET' }, { code: 'POST' }, { code: 'HEAD' }, { code: 'PUT' }, { code: 'DELETE' }],
httpCheckCondition: 'STATUS_CODE_DEFAULT',
httpCheckConditionList: cookie.get('language') == 'en_US'? [{ code: 'STATUS_CODE_DEFAULT',value:'Default response code 200' }, { code: 'STATUS_CODE_CUSTOM',value:'Custom response code' }, { code: 'BODY_CONTAINS',value:'Content includes' }, { code: 'BODY_NOT_CONTAINS',value:'Content does not contain' }]:[{ code: 'STATUS_CODE_DEFAULT',value:'默认响应码200' }, { code: 'STATUS_CODE_CUSTOM',value:'自定义响应码' }, { code: 'BODY_CONTAINS',value:'内容包含' }, { code: 'BODY_NOT_CONTAINS',value:'内容不包含' }]
httpCheckConditionList: cookies.get('language') == 'en_US'? [{ code: 'STATUS_CODE_DEFAULT',value:'Default response code 200' }, { code: 'STATUS_CODE_CUSTOM',value:'Custom response code' }, { code: 'BODY_CONTAINS',value:'Content includes' }, { code: 'BODY_NOT_CONTAINS',value:'Content does not contain' }]:[{ code: 'STATUS_CODE_DEFAULT',value:'默认响应码200' }, { code: 'STATUS_CODE_CUSTOM',value:'自定义响应码' }, { code: 'BODY_CONTAINS',value:'内容包含' }, { code: 'BODY_NOT_CONTAINS',value:'内容不包含' }]
}
},
props: {

1
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/dragZoom.js

@ -1,4 +1,3 @@
import $ from 'jquery'
import d3 from 'd3'
/*
* Licensed to the Apache Software Foundation (ASF) under one or more

6
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/jsPlumbHandle.js

@ -14,9 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'jquery-ui/ui/widgets/draggable'
import 'jquery-ui/ui/widgets/droppable'
import 'jquery-ui/ui/widgets/resizable'
import Vue from 'vue'
import $ from 'jquery'
import _ from 'lodash'
import i18n from '@/module/i18n'
import { jsPlumb } from 'jsplumb'
@ -25,6 +26,7 @@ import store from '@/conf/home/store'
import router from '@/conf/home/router'
import Permissions from '@/module/permissions'
import { uuid, findComponentDownward } from '@/module/util/'
import {
tasksAll,
rtTasksTpl,

1
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/plugIn/util.js

@ -16,7 +16,6 @@
*/
import _ from 'lodash'
import $ from 'jquery'
import i18n from '@/module/i18n'
import store from '@/conf/home/store'

1
dolphinscheduler-ui/src/js/conf/home/pages/monitor/pages/servers/_source/gauge.vue

@ -25,6 +25,7 @@
</div>
</template>
<script>
import echarts from 'echarts'
import gaugeOption from './gaugeOption'
export default {

9
dolphinscheduler-ui/src/js/conf/home/pages/monitor/pages/servers/_source/gaugeOption.js

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import echarts from 'echarts'
export default function (value) {
return {
series: [
@ -36,23 +37,23 @@ export default function (value) {
}], false) ], // 100% Color in place
[ 0.7, new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ // eslint-disable-line
offset: 1,
color: '#C7DD6B'// 70% Color in place
color: '#FFC539'// 70% Color in place
}, {
offset: 0.8,
color: '#FEEC49'// 66% Color in place
}, {
offset: 0,
color: '#FFC539'// 50% Color in place
color: '#C7DD6B'// 50% Color in place
}], false) ],
[ 0.9, new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ // eslint-disable-line
offset: 1,
color: '#FFC539' // 90% Color in place
color: '#E75F25' // 90% Color in place
}, {
offset: 0.8,
color: '#FE951E' // 86% Color in place
}, {
offset: 0,
color: '#E75F25' // 70% Color in place
color: '#FFC539' // 70% Color in place
}], false) ],
[1, new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { // eslint-disable-line
offset: 0.2,

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

@ -81,8 +81,8 @@
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('Edit')" @click="_edit(item)" :disabled="item.releaseState === 'ONLINE'" icon="ans-icon-edit"><!--{{$t('编辑')}}--></x-button>
<x-button type="success" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('Start')" @click="_start(item)" :disabled="item.releaseState !== 'ONLINE'" icon="ans-icon-play"><!--{{$t('启动')}}--></x-button>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('Timing')" @click="_timing(item)" :disabled="item.releaseState !== 'ONLINE' || item.scheduleReleaseState !== null" icon="ans-icon-timer"><!--{{$t('定时')}}--></x-button>
<x-button type="warning" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('online')" @click="_poponline(item)" v-if="item.releaseState === 'OFFLINE'" icon="ans-icon-downward"><!--{{$t('下线')}}--></x-button>
<x-button type="error" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('offline')" @click="_downline(item)" v-if="item.releaseState === 'ONLINE'" icon="ans-icon-upward"><!--{{$t('上线')}}--></x-button>
<x-button type="warning" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('online')" @click="_poponline(item)" v-if="item.releaseState === 'OFFLINE'" icon="ans-icon-upward"><!--{{$t('下线')}}--></x-button>
<x-button type="error" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('offline')" @click="_downline(item)" v-if="item.releaseState === 'ONLINE'" icon="ans-icon-downward"><!--{{$t('上线')}}--></x-button>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('Cron Manage')" @click="_timingManage(item)" :disabled="item.releaseState !== 'ONLINE'" icon="ans-icon-datetime"><!--{{$t('定时管理')}}--></x-button>
<x-poptip
:ref="'poptip-delete-' + $index"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save