[Feature-10411] Add tenant api test (#10442)
* add feature_10411 * add feature_10411 * update README.md * fix README.md deadlink * fix error log output * fix comment
This commit is contained in:
parent
d516369e80
commit
e50739465d
|
|
@ -0,0 +1,139 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
name: API-Test
|
||||
|
||||
concurrency:
|
||||
group: api-test-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
paths-filter:
|
||||
name: API-Test-Path-Filter
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
not-ignore: ${{ steps.filter.outputs.not-ignore }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
not-ignore:
|
||||
- '!(docs/**)'
|
||||
build:
|
||||
name: API-Test-Build
|
||||
needs: paths-filter
|
||||
if: ${{ (needs.paths-filter.outputs.not-ignore == 'true') || (github.event_name == 'push') }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Sanity Check
|
||||
uses: ./.github/actions/sanity-check
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
- name: Build Image
|
||||
run: |
|
||||
./mvnw -B clean install \
|
||||
-Dmaven.test.skip \
|
||||
-Dmaven.javadoc.skip \
|
||||
-Dmaven.checkstyle.skip \
|
||||
-Pdocker,release -Ddocker.tag=ci \
|
||||
-pl dolphinscheduler-standalone-server -am
|
||||
- name: Export Docker Images
|
||||
run: |
|
||||
docker save apache/dolphinscheduler-standalone-server:ci -o /tmp/standalone-image.tar \
|
||||
&& du -sh /tmp/standalone-image.tar
|
||||
- uses: actions/upload-artifact@v2
|
||||
name: Upload Docker Images
|
||||
with:
|
||||
name: standalone-image
|
||||
path: /tmp/standalone-image.tar
|
||||
retention-days: 1
|
||||
api-test:
|
||||
name: ${{ matrix.case.name }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
matrix:
|
||||
case:
|
||||
- name: Tenant
|
||||
class: org.apache.dolphinscheduler.api.test.cases.TenantAPITest
|
||||
env:
|
||||
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
- uses: actions/download-artifact@v2
|
||||
name: Download Docker Images
|
||||
with:
|
||||
name: standalone-image
|
||||
path: /tmp
|
||||
- name: Load Docker Images
|
||||
run: |
|
||||
docker load -i /tmp/standalone-image.tar
|
||||
- name: Run Test
|
||||
run: |
|
||||
./mvnw -B -f dolphinscheduler-api-test/pom.xml -am \
|
||||
-DfailIfNoTests=false \
|
||||
-Dtest=${{ matrix.case.class }} test
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
name: Upload Recording
|
||||
with:
|
||||
name: recording-${{ matrix.case.name }}
|
||||
path: ${{ env.RECORDING_PATH }}
|
||||
retention-days: 1
|
||||
result:
|
||||
name: API-Test-Result
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
needs: [ api-test, paths-filter ]
|
||||
if: always()
|
||||
steps:
|
||||
- name: Status
|
||||
run: |
|
||||
if [[ ${{ needs.paths-filter.outputs.not-ignore }} == 'false' && ${{ github.event_name }} == 'pull_request' ]]; then
|
||||
echo "Skip API Test!"
|
||||
exit 0
|
||||
fi
|
||||
if [[ ${{ needs.api-test.result }} != 'success' ]]; then
|
||||
echo "API test Failed!"
|
||||
exit -1
|
||||
fi
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# DolphinScheduler Backend API Test
|
||||
|
||||
## Page Object Model
|
||||
|
||||
DolphinScheduler API test respects
|
||||
the [Page Object Model (POM)](https://www.selenium.dev/documentation/guidelines/page_object_models/) design pattern.
|
||||
Every page of DolphinScheduler's api is abstracted into a class for better maintainability.
|
||||
|
||||
### Example
|
||||
|
||||
The login page's api is abstracted
|
||||
as [`LoginPage`](dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api.test/pages/LoginPage.java), with the
|
||||
following fields,
|
||||
|
||||
```java
|
||||
public HttpResponse login(String username, String password) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
|
||||
params.put("userName", username);
|
||||
params.put("userPassword", password);
|
||||
|
||||
RequestClient requestClient = new RequestClient();
|
||||
|
||||
return requestClient.post("/login", null, params);
|
||||
}
|
||||
```
|
||||
|
||||
where `userName`, `userPassword` are the main elements on UI that we are interested in.
|
||||
|
||||
## Test Environment Setup
|
||||
|
||||
DolphinScheduler API test uses [testcontainers](https://www.testcontainers.org) to set up the testing
|
||||
environment, with docker compose.
|
||||
|
||||
Typically, every test case needs one or more `docker-compose.yaml` files to set up all needed components, and expose the
|
||||
DolphinScheduler UI port for testing. You can use `@DolphinScheduler(composeFiles = "")` and pass
|
||||
the `docker-compose.yaml` files to automatically set up the environment in the test class.
|
||||
|
||||
```java
|
||||
|
||||
@DolphinScheduler(composeFiles = "docker/tenant/docker-compose.yaml")
|
||||
class TenantAPITest {
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to 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. Apache Software Foundation (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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dolphinscheduler-api-test</artifactId>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>dolphinscheduler-api-test-case</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-api-test-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.cases;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.api.test.core.DolphinScheduler;
|
||||
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
|
||||
import org.apache.dolphinscheduler.api.test.entity.LoginResponseData;
|
||||
import org.apache.dolphinscheduler.api.test.entity.TenantListPagingResponseData;
|
||||
import org.apache.dolphinscheduler.api.test.entity.TenantListPagingResponseTotalList;
|
||||
import org.apache.dolphinscheduler.api.test.pages.LoginPage;
|
||||
import org.apache.dolphinscheduler.api.test.pages.security.TenantPage;
|
||||
import org.apache.dolphinscheduler.api.test.utils.JSONUtils;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
|
||||
@Slf4j
|
||||
public class TenantAPITest {
|
||||
private static final String tenant = System.getProperty("user.name");
|
||||
|
||||
private static final String user = "admin";
|
||||
|
||||
private static final String password = "dolphinscheduler123";
|
||||
|
||||
private static String sessionId = null;
|
||||
|
||||
private static Integer existTenantId = null;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
LoginPage loginPage = new LoginPage();
|
||||
HttpResponse loginHttpResponse = loginPage.login(user, password);
|
||||
|
||||
sessionId = JSONUtils.convertValue(loginHttpResponse.body().data(), LoginResponseData.class).sessionId();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void cleanup() {
|
||||
LOGGER.info("success cleanup");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void testCreateTenant() {
|
||||
TenantPage tenantPage = new TenantPage();
|
||||
|
||||
HttpResponse createTenantHttpResponse = tenantPage.createTenant(sessionId, tenant, 1, "");
|
||||
|
||||
Assertions.assertTrue(createTenantHttpResponse.body().success());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testDuplicateCreateTenant() {
|
||||
TenantPage tenantPage = new TenantPage();
|
||||
|
||||
HttpResponse createTenantHttpResponse = tenantPage.createTenant(sessionId, tenant, 1, "");
|
||||
|
||||
Assertions.assertFalse(createTenantHttpResponse.body().success());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
public void testGetTenantListPaging() {
|
||||
TenantPage tenantPage = new TenantPage();
|
||||
|
||||
HttpResponse createTenantHttpResponse = tenantPage.getTenantListPaging(sessionId, 1, 10, "");
|
||||
boolean result = false;
|
||||
|
||||
for (TenantListPagingResponseTotalList tenantListPagingResponseTotalList : JSONUtils.convertValue(createTenantHttpResponse.body().data(), TenantListPagingResponseData.class).totalList()) {
|
||||
if (tenantListPagingResponseTotalList.tenantCode().equals(tenant)) {
|
||||
result = true;
|
||||
existTenantId = tenantListPagingResponseTotalList.id();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assertions.assertTrue(createTenantHttpResponse.body().success());
|
||||
Assertions.assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(10)
|
||||
public void testDeleteTenant() {
|
||||
TenantPage tenantPage = new TenantPage();
|
||||
|
||||
HttpResponse deleteTenantHttpResponse = tenantPage.deleteTenant(sessionId, existTenantId);
|
||||
|
||||
Assertions.assertTrue(deleteTenantHttpResponse.body().success());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class HttpResponse {
|
||||
|
||||
private int statusCode;
|
||||
|
||||
private HttpResponseBody body;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class HttpResponseBody {
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String msg;
|
||||
|
||||
private Object data;
|
||||
|
||||
private Boolean failed;
|
||||
|
||||
private Boolean success;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class LoginResponseData {
|
||||
|
||||
private String sessionId;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class TenantListPagingResponseData {
|
||||
private Integer currentPage;
|
||||
|
||||
private Integer pageSize;
|
||||
|
||||
private Integer start;
|
||||
|
||||
private Integer total;
|
||||
|
||||
private List<TenantListPagingResponseTotalList> totalList;
|
||||
|
||||
private Integer totalPage;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class TenantListPagingResponseTotalList {
|
||||
private Date createTime;
|
||||
|
||||
private Date updateTime;
|
||||
|
||||
private String description;
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String queue;
|
||||
|
||||
private Integer queueId;
|
||||
|
||||
private String queueName;
|
||||
|
||||
private String tenantCode;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.pages;
|
||||
|
||||
|
||||
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
|
||||
import org.apache.dolphinscheduler.api.test.utils.RequestClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class LoginPage {
|
||||
public HttpResponse login(String username, String password) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
|
||||
params.put("userName", username);
|
||||
params.put("userPassword", password);
|
||||
|
||||
RequestClient requestClient = new RequestClient();
|
||||
|
||||
return requestClient.post("/login", null, params);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.pages.security;
|
||||
|
||||
|
||||
import org.apache.dolphinscheduler.api.test.core.Constants;
|
||||
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
|
||||
import org.apache.dolphinscheduler.api.test.utils.RequestClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class TenantPage {
|
||||
public HttpResponse createTenant(String sessionId, String tenant, Integer queueId, String description) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("tenantCode", tenant);
|
||||
params.put("queueId", queueId);
|
||||
params.put("description", description);
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(Constants.SESSION_ID_KEY, sessionId);
|
||||
|
||||
RequestClient requestClient = new RequestClient();
|
||||
|
||||
return requestClient.post("/tenants", headers, params);
|
||||
}
|
||||
|
||||
public HttpResponse getTenantListPaging(String sessionId, Integer pageNo, Integer pageSize, String searchVal) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(Constants.SESSION_ID_KEY, sessionId);
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("pageSize", pageSize);
|
||||
params.put("pageNo", pageNo);
|
||||
params.put("searchVal", searchVal);
|
||||
|
||||
RequestClient requestClient = new RequestClient();
|
||||
|
||||
return requestClient.get("/tenants/", headers, params);
|
||||
}
|
||||
|
||||
public HttpResponse deleteTenant(String sessionId, Integer tenantId) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(Constants.SESSION_ID_KEY, sessionId);
|
||||
|
||||
RequestClient requestClient = new RequestClient();
|
||||
|
||||
return requestClient.delete(String.format("/tenants/%s", tenantId), headers, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* 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.test.utils;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT;
|
||||
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
|
||||
import static com.fasterxml.jackson.databind.DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL;
|
||||
import static com.fasterxml.jackson.databind.MapperFeature.REQUIRE_SETTERS_FOR_GETTERS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.dolphinscheduler.api.test.core.Constants;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import org.testcontainers.shaded.org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* json utils
|
||||
*/
|
||||
public class JSONUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JSONUtils.class);
|
||||
|
||||
static {
|
||||
logger.info("init timezone: {}",TimeZone.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* can use static singleton, inject: just make sure to reuse!
|
||||
*/
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper()
|
||||
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true)
|
||||
.configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
|
||||
.configure(REQUIRE_SETTERS_FOR_GETTERS, true)
|
||||
.setTimeZone(TimeZone.getDefault())
|
||||
.setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS));
|
||||
|
||||
private JSONUtils() {
|
||||
throw new UnsupportedOperationException("Construct JSONUtils");
|
||||
}
|
||||
|
||||
public static ArrayNode createArrayNode() {
|
||||
return objectMapper.createArrayNode();
|
||||
}
|
||||
|
||||
public static ObjectNode createObjectNode() {
|
||||
return objectMapper.createObjectNode();
|
||||
}
|
||||
|
||||
public static JsonNode toJsonNode(Object obj) {
|
||||
return objectMapper.valueToTree(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* json representation of object
|
||||
*
|
||||
* @param object object
|
||||
* @param feature feature
|
||||
* @return object to json string
|
||||
*/
|
||||
public static String toJsonString(Object object, SerializationFeature feature) {
|
||||
try {
|
||||
ObjectWriter writer = objectMapper.writer(feature);
|
||||
return writer.writeValueAsString(object);
|
||||
} catch (Exception e) {
|
||||
logger.error("object to json exception!", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method deserializes the specified Json into an object of the specified class. It is not
|
||||
* suitable to use if the specified class is a generic type since it will not have the generic
|
||||
* type information because of the Type Erasure feature of Java. Therefore, this method should not
|
||||
* be used if the desired type is a generic type. Note that this method works fine if the any of
|
||||
* the fields of the specified object are generics, just the object itself should not be a
|
||||
* generic type.
|
||||
*
|
||||
* @param json the string from which the object is to be deserialized
|
||||
* @param clazz the class of T
|
||||
* @param <T> T
|
||||
* @return an object of type T from the string
|
||||
* classOfT
|
||||
*/
|
||||
public static <T> T parseObject(String json, Class<T> clazz) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return objectMapper.readValue(json, clazz);
|
||||
} catch (Exception e) {
|
||||
logger.error("parse object exception!", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* deserialize
|
||||
*
|
||||
* @param src byte array
|
||||
* @param clazz class
|
||||
* @param <T> deserialize type
|
||||
* @return deserialize type
|
||||
*/
|
||||
public static <T> T parseObject(byte[] src, Class<T> clazz) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
String json = new String(src, UTF_8);
|
||||
return parseObject(json, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* json to list
|
||||
*
|
||||
* @param json json string
|
||||
* @param clazz class
|
||||
* @param <T> T
|
||||
* @return list
|
||||
*/
|
||||
public static <T> List<T> toList(String json, Class<T> clazz) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
|
||||
return objectMapper.readValue(json, listType);
|
||||
} catch (Exception e) {
|
||||
logger.error("parse list exception!", e);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* check json object valid
|
||||
*
|
||||
* @param json json
|
||||
* @return true if valid
|
||||
*/
|
||||
public static boolean checkJsonValid(String json) {
|
||||
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
objectMapper.readTree(json);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.error("check json object valid exception!", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for finding a JSON Object field with specified name in this
|
||||
* node or its child nodes, and returning value it has.
|
||||
* If no matching field is found in this node or its descendants, returns null.
|
||||
*
|
||||
* @param jsonNode json node
|
||||
* @param fieldName Name of field to look for
|
||||
* @return Value of first matching node found, if any; null if none
|
||||
*/
|
||||
public static String findValue(JsonNode jsonNode, String fieldName) {
|
||||
JsonNode node = jsonNode.findValue(fieldName);
|
||||
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return node.asText();
|
||||
}
|
||||
|
||||
/**
|
||||
* json to map
|
||||
* {@link #toMap(String, Class, Class)}
|
||||
*
|
||||
* @param json json
|
||||
* @return json to map
|
||||
*/
|
||||
public static Map<String, String> toMap(String json) {
|
||||
return parseObject(json, new TypeReference<Map<String, String>>() {});
|
||||
}
|
||||
|
||||
/**
|
||||
* json to map
|
||||
*
|
||||
* @param json json
|
||||
* @param classK classK
|
||||
* @param classV classV
|
||||
* @param <K> K
|
||||
* @param <V> V
|
||||
* @return to map
|
||||
*/
|
||||
public static <K, V> Map<K, V> toMap(String json, Class<K> classK, Class<V> classV) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
try {
|
||||
return objectMapper.readValue(json, new TypeReference<Map<K, V>>() {
|
||||
});
|
||||
} catch (Exception e) {
|
||||
logger.error("json to map exception!", e);
|
||||
}
|
||||
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* from the key-value generated json to get the str value no matter the real type of value
|
||||
* @param json the json str
|
||||
* @param nodeName key
|
||||
* @return the str value of key
|
||||
*/
|
||||
public static String getNodeString(String json, String nodeName) {
|
||||
try {
|
||||
JsonNode rootNode = objectMapper.readTree(json);
|
||||
JsonNode jsonNode = rootNode.findValue(nodeName);
|
||||
if (Objects.isNull(jsonNode)) {
|
||||
return "";
|
||||
}
|
||||
return jsonNode.isTextual() ? jsonNode.asText() : jsonNode.toString();
|
||||
} catch (JsonProcessingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json to object
|
||||
*
|
||||
* @param json json string
|
||||
* @param type type reference
|
||||
* @param <T>
|
||||
* @return return parse object
|
||||
*/
|
||||
public static <T> T parseObject(String json, TypeReference<T> type) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return objectMapper.readValue(json, type);
|
||||
} catch (Exception e) {
|
||||
logger.error("json to map exception!", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* object to json string
|
||||
*
|
||||
* @param object object
|
||||
* @return json string
|
||||
*/
|
||||
public static String toJsonString(Object object) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(object);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Object json deserialization exception.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* serialize to json byte
|
||||
*
|
||||
* @param obj object
|
||||
* @param <T> object type
|
||||
* @return byte array
|
||||
*/
|
||||
public static <T> byte[] toJsonByteArray(T obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
String json = "";
|
||||
try {
|
||||
json = toJsonString(obj);
|
||||
} catch (Exception e) {
|
||||
logger.error("json serialize exception.", e);
|
||||
}
|
||||
|
||||
return json.getBytes(UTF_8);
|
||||
}
|
||||
|
||||
public static ObjectNode parseObject(String text) {
|
||||
try {
|
||||
if (text.isEmpty()) {
|
||||
return parseObject(text, ObjectNode.class);
|
||||
} else {
|
||||
return (ObjectNode) objectMapper.readTree(text);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("String json deserialization exception.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayNode parseArray(String text) {
|
||||
try {
|
||||
return (ArrayNode) objectMapper.readTree(text);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Json deserialization exception.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json serializer
|
||||
*/
|
||||
public static class JsonDataSerializer extends JsonSerializer<String> {
|
||||
|
||||
@Override
|
||||
public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
gen.writeRawValue(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* json data deserializer
|
||||
*/
|
||||
public static class JsonDataDeserializer extends JsonDeserializer<String> {
|
||||
|
||||
@Override
|
||||
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
JsonNode node = p.getCodec().readTree(p);
|
||||
if (node instanceof TextNode) {
|
||||
return node.asText();
|
||||
} else {
|
||||
return node.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <T> T convertValue(Object value, Class<T> targetType) {
|
||||
return objectMapper.convertValue(value, targetType);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.api.test.core.Constants;
|
||||
import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
|
||||
import org.apache.dolphinscheduler.api.test.entity.HttpResponseBody;
|
||||
import org.testcontainers.shaded.okhttp3.FormBody;
|
||||
import org.testcontainers.shaded.okhttp3.Headers;
|
||||
import org.testcontainers.shaded.okhttp3.MediaType;
|
||||
import org.testcontainers.shaded.okhttp3.OkHttpClient;
|
||||
import org.testcontainers.shaded.okhttp3.Request;
|
||||
import org.testcontainers.shaded.okhttp3.RequestBody;
|
||||
import org.testcontainers.shaded.okhttp3.Response;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public class RequestClient {
|
||||
|
||||
private OkHttpClient httpClient = null;
|
||||
|
||||
public RequestClient() {
|
||||
this.httpClient = new OkHttpClient();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public HttpResponse get(String url, Map<String, String> headers, Map<String, Object> params) {
|
||||
String requestUrl = String.format("%s%s%s", Constants.DOLPHINSCHEDULER_API_URL, url, getParams(params));
|
||||
|
||||
Headers headersBuilder = new Headers.Builder().build();
|
||||
if (headers != null) {
|
||||
headersBuilder = Headers.of(headers);
|
||||
}
|
||||
|
||||
LOGGER.info("GET request to {}, Headers: {}", requestUrl, headersBuilder);
|
||||
Request request = new Request.Builder()
|
||||
.url(requestUrl)
|
||||
.headers(headersBuilder)
|
||||
.get()
|
||||
.build();
|
||||
|
||||
Response response = this.httpClient.newCall(request).execute();
|
||||
|
||||
HttpResponseBody responseData = null;
|
||||
int responseCode = response.code();
|
||||
if (response.body() != null) {
|
||||
responseData = JSONUtils.parseObject(response.body().string(), HttpResponseBody.class);
|
||||
}
|
||||
response.close();
|
||||
|
||||
HttpResponse httpResponse = new HttpResponse(responseCode, responseData);
|
||||
|
||||
LOGGER.info("GET response: {}", httpResponse);
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
public static String getParams(Map<String, Object> params) {
|
||||
StringBuilder sb = new StringBuilder(Constants.QUESTION_MARK);
|
||||
if (params.size() > 0) {
|
||||
for (Map.Entry<String, Object> item : params.entrySet()) {
|
||||
Object value = item.getValue();
|
||||
if (Objects.nonNull(value)) {
|
||||
sb.append(Constants.AND_MARK);
|
||||
sb.append(item.getKey());
|
||||
sb.append(Constants.EQUAL_MARK);
|
||||
sb.append(value);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public HttpResponse post(String url, Map<String, String> headers, Map<String, Object> params) {
|
||||
if (headers == null) {
|
||||
headers = new HashMap<>();
|
||||
}
|
||||
|
||||
String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url);
|
||||
|
||||
headers.put("Content-Type", Constants.REQUEST_CONTENT_TYPE);
|
||||
|
||||
Headers headersBuilder = Headers.of(headers);
|
||||
|
||||
RequestBody requestBody = FormBody.create(MediaType.parse(Constants.REQUEST_CONTENT_TYPE), getParams(params));
|
||||
|
||||
LOGGER.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
|
||||
Request request = new Request.Builder()
|
||||
.headers(headersBuilder)
|
||||
.url(requestUrl)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
|
||||
Response response = this.httpClient.newCall(request).execute();
|
||||
|
||||
|
||||
int responseCode = response.code();
|
||||
HttpResponseBody responseData = null;
|
||||
if (response.body() != null) {
|
||||
responseData = JSONUtils.parseObject(response.body().string(), HttpResponseBody.class);
|
||||
}
|
||||
response.close();
|
||||
|
||||
HttpResponse httpResponse = new HttpResponse(responseCode, responseData);
|
||||
|
||||
LOGGER.info("POST response: {}", httpResponse);
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public HttpResponse delete(String url, Map<String, String> headers, Map<String, Object> params) {
|
||||
if (headers == null) {
|
||||
headers = new HashMap<>();
|
||||
}
|
||||
|
||||
String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url);
|
||||
|
||||
headers.put("Content-Type", Constants.REQUEST_CONTENT_TYPE);
|
||||
|
||||
Headers headersBuilder = Headers.of(headers);
|
||||
|
||||
LOGGER.info("DELETE request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params);
|
||||
Request request = new Request.Builder()
|
||||
.headers(headersBuilder)
|
||||
.url(requestUrl)
|
||||
.delete()
|
||||
.build();
|
||||
|
||||
Response response = this.httpClient.newCall(request).execute();
|
||||
|
||||
|
||||
int responseCode = response.code();
|
||||
HttpResponseBody responseData = null;
|
||||
if (response.body() != null) {
|
||||
responseData = JSONUtils.parseObject(response.body().string(), HttpResponseBody.class);
|
||||
}
|
||||
response.close();
|
||||
|
||||
HttpResponse httpResponse = new HttpResponse(responseCode, responseData);
|
||||
|
||||
LOGGER.info("DELETE response: {}", httpResponse);
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
depends_on:
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
clickhouse:
|
||||
image: yandex/clickhouse-server:21.12.3.32
|
||||
environment:
|
||||
- CLICKHOUSE_DB=ch_test
|
||||
- CLICKHOUSE_USER=ch_test
|
||||
- CLICKHOUSE_PASSWORD=ch_test
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 262144
|
||||
hard: 262144
|
||||
expose:
|
||||
- 8123
|
||||
mem_limit: 3G
|
||||
mem_reservation: 1G
|
||||
networks:
|
||||
- e2e
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "-q", "localhost:8123/ping"]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
depends_on:
|
||||
hive-server:
|
||||
condition: service_healthy
|
||||
namenode:
|
||||
image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8
|
||||
environment:
|
||||
- CLUSTER_NAME=test
|
||||
env_file:
|
||||
- ./hadoop-hive.env
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- "50070"
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:50070/" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
datanode:
|
||||
image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8
|
||||
env_file:
|
||||
- ./hadoop-hive.env
|
||||
environment:
|
||||
SERVICE_PRECONDITION: "namenode:50070"
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- "50075"
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:50075" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
hive-server:
|
||||
image: bde2020/hive:2.3.2-postgresql-metastore
|
||||
env_file:
|
||||
- ./hadoop-hive.env
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore"
|
||||
SERVICE_PRECONDITION: "hive-metastore:9083"
|
||||
expose:
|
||||
- "10000"
|
||||
depends_on:
|
||||
datanode:
|
||||
condition: service_healthy
|
||||
namenode:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: beeline -u "jdbc:hive2://127.0.0.1:10000/default" -n health_check -e "show databases;"
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
hive-metastore:
|
||||
image: bde2020/hive:2.3.2-postgresql-metastore
|
||||
env_file:
|
||||
- ./hadoop-hive.env
|
||||
command: /opt/hive/bin/hive --service metastore
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432"
|
||||
expose:
|
||||
- "9083"
|
||||
depends_on:
|
||||
hive-metastore-postgresql:
|
||||
condition: service_healthy
|
||||
hive-metastore-postgresql:
|
||||
image: bde2020/hive-metastore-postgresql:2.3.0
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- "5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
HIVE_SITE_CONF_javax_jdo_option_ConnectionURL=jdbc:postgresql://hive-metastore-postgresql/metastore
|
||||
HIVE_SITE_CONF_javax_jdo_option_ConnectionDriverName=org.postgresql.Driver
|
||||
HIVE_SITE_CONF_javax_jdo_option_ConnectionUserName=hive
|
||||
HIVE_SITE_CONF_javax_jdo_option_ConnectionPassword=hive
|
||||
HIVE_SITE_CONF_datanucleus_autoCreateSchema=false
|
||||
HIVE_SITE_CONF_hive_metastore_uris=thrift://hive-metastore:9083
|
||||
HDFS_CONF_dfs_namenode_datanode_registration_ip___hostname___check=false
|
||||
HIVE_SITE_CONF_hive_server2_thrift_bind_host=0.0.0.0
|
||||
HIVE_SITE_CONF_hive_server2_thrift_port=10000
|
||||
|
||||
CORE_CONF_fs_defaultFS=hdfs://namenode:8020
|
||||
CORE_CONF_hadoop_http_staticuser_user=root
|
||||
CORE_CONF_hadoop_proxyuser_hue_hosts=*
|
||||
CORE_CONF_hadoop_proxyuser_hue_groups=*
|
||||
CORE_CONF_hadoop_proxyuser_hive_hosts=*
|
||||
|
||||
HDFS_CONF_dfs_webhdfs_enabled=true
|
||||
HDFS_CONF_dfs_permissions_enabled=false
|
||||
|
||||
YARN_CONF_yarn_log___aggregation___enable=true
|
||||
YARN_CONF_yarn_resourcemanager_recovery_enabled=true
|
||||
YARN_CONF_yarn_resourcemanager_store_class=org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore
|
||||
YARN_CONF_yarn_resourcemanager_fs_state___store_uri=/rmstate
|
||||
YARN_CONF_yarn_nodemanager_remote___app___log___dir=/app-logs
|
||||
YARN_CONF_yarn_log_server_url=http://historyserver:8188/applicationhistory/logs/
|
||||
YARN_CONF_yarn_timeline___service_enabled=true
|
||||
YARN_CONF_yarn_timeline___service_generic___application___history_enabled=true
|
||||
YARN_CONF_yarn_resourcemanager_system___metrics___publisher_enabled=true
|
||||
YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
|
||||
YARN_CONF_yarn_timeline___service_hostname=historyserver
|
||||
YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032
|
||||
YARN_CONF_yarn_resourcemanager_scheduler_address=resourcemanager:8030
|
||||
YARN_CONF_yarn_resourcemanager_resource__tracker_address=resourcemanager:8031
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
volumes:
|
||||
- ./download-mysql.sh:/tmp/download-mysql.sh
|
||||
entrypoint: [ 'bash', '-c', '/bin/bash /tmp/download-mysql.sh && /opt/dolphinscheduler/bin/start.sh && tail -f /dev/null' ]
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
mysql:
|
||||
image: mysql:5.7.36
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
expose:
|
||||
- 3306
|
||||
healthcheck:
|
||||
test: mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
set -ex
|
||||
|
||||
DS_HOME=/opt/dolphinscheduler/libs/standalone-server
|
||||
MYSQL_URL="https://repo.maven.apache.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar"
|
||||
MYSQL_DRIVER="mysql-connector-java-8.0.16.jar"
|
||||
|
||||
if ! curl -Lo "${DS_HOME}/${MYSQL_DRIVER}" ${MYSQL_URL}; then
|
||||
echo "Fail to download ${MYSQL_DRIVER}."
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
image: postgres:14.1
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 5432
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
depends_on:
|
||||
sqlserver:
|
||||
condition: service_healthy
|
||||
sqlserver:
|
||||
image: alexk002/sqlserver2019_demo:1
|
||||
expose:
|
||||
- 1433
|
||||
networks:
|
||||
- e2e
|
||||
healthcheck:
|
||||
test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P OcP2020123 -Q "SELECT 1"
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# user data local directory path, please make sure the directory exists and have read write permissions
|
||||
data.basedir.path=/tmp/dolphinscheduler
|
||||
|
||||
# resource storage type: HDFS, S3, NONE
|
||||
resource.storage.type=S3
|
||||
|
||||
# resource store on HDFS/S3 path, resource file will store to this hadoop hdfs path, self configuration, please make sure the directory exists on hdfs and have read write permissions. "/dolphinscheduler" is recommended
|
||||
resource.upload.path=/dolphinscheduler
|
||||
|
||||
# whether to startup kerberos
|
||||
hadoop.security.authentication.startup.state=false
|
||||
|
||||
# java.security.krb5.conf path
|
||||
java.security.krb5.conf.path=/opt/krb5.conf
|
||||
|
||||
# login user from keytab username
|
||||
login.user.keytab.username=hdfs-mycluster@ESZ.COM
|
||||
|
||||
# login user from keytab path
|
||||
login.user.keytab.path=/opt/hdfs.headless.keytab
|
||||
|
||||
# kerberos expire time, the unit is hour
|
||||
kerberos.expire.time=2
|
||||
|
||||
# resource view suffixs
|
||||
#resource.view.suffixs=txt,log,sh,bat,conf,cfg,py,java,sql,xml,hql,properties,json,yml,yaml,ini,js
|
||||
|
||||
# if resource.storage.type=HDFS, the user must have the permission to create directories under the HDFS root path
|
||||
hdfs.root.user=hdfs
|
||||
|
||||
# if resource.storage.type=S3, the value like: s3a://dolphinscheduler; if resource.storage.type=HDFS and namenode HA is enabled, you need to copy core-site.xml and hdfs-site.xml to conf dir
|
||||
fs.defaultFS=s3a://dolphinscheduler
|
||||
|
||||
|
||||
# resourcemanager port, the default value is 8088 if not specified
|
||||
resource.manager.httpaddress.port=8088
|
||||
|
||||
# if resourcemanager HA is enabled, please set the HA IPs; if resourcemanager is single, keep this value empty
|
||||
yarn.resourcemanager.ha.rm.ids=192.168.xx.xx,192.168.xx.xx
|
||||
|
||||
# if resourcemanager HA is enabled or not use resourcemanager, please keep the default value; If resourcemanager is single, you only need to replace ds1 to actual resourcemanager hostname
|
||||
yarn.application.status.address=http://ds1:%s/ws/v1/cluster/apps/%s
|
||||
|
||||
# job history status url when application number threshold is reached(default 10000, maybe it was set to 1000)
|
||||
yarn.job.history.status.address=http://ds1:19888/ws/v1/history/mapreduce/jobs/%s
|
||||
|
||||
# datasource encryption enable
|
||||
datasource.encryption.enable=false
|
||||
|
||||
# datasource encryption salt
|
||||
datasource.encryption.salt=!@#$%^&*
|
||||
|
||||
# use sudo or not, if set true, executing user is tenant user and deploy user needs sudo permissions; if set false, executing user is the deploy user and doesn't need sudo permissions
|
||||
sudo.enable=true
|
||||
|
||||
# network interface preferred like eth0, default: empty
|
||||
#dolphin.scheduler.network.interface.preferred=
|
||||
|
||||
# network IP gets priority, default: inner outer
|
||||
#dolphin.scheduler.network.priority.strategy=default
|
||||
# system env path
|
||||
#dolphinscheduler.env.path=dolphinscheduler_env.sh
|
||||
# development state
|
||||
development.state=false
|
||||
# rpc port
|
||||
alert.rpc.port=50052
|
||||
aws.access.key.id=accessKey123
|
||||
aws.secret.access.key=secretKey123
|
||||
aws.region=us-east-1
|
||||
aws.endpoint=http://s3:9000
|
||||
|
||||
# Task resource limit state
|
||||
task.resource.limit.state=false
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
dolphinscheduler:
|
||||
image: apache/dolphinscheduler-standalone-server:ci
|
||||
environment:
|
||||
MASTER_MAX_CPU_LOAD_AVG: 100
|
||||
WORKER_TENANT_AUTO_CREATE: 'true'
|
||||
ports:
|
||||
- "12345:12345"
|
||||
networks:
|
||||
- api-test
|
||||
healthcheck:
|
||||
test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
volumes:
|
||||
- ./common.properties:/opt/dolphinscheduler/conf/common.properties
|
||||
depends_on:
|
||||
s3:
|
||||
condition: service_healthy
|
||||
mc:
|
||||
condition: service_completed_successfully
|
||||
s3:
|
||||
image: minio/minio:RELEASE.2022-01-25T19-56-04Z
|
||||
hostname: s3
|
||||
tty: true
|
||||
stdin_open: true
|
||||
command: server /data --console-address ":9001"
|
||||
ports:
|
||||
- 9000:9000
|
||||
networks:
|
||||
- e2e
|
||||
environment:
|
||||
MINIO_ROOT_USER: accessKey123
|
||||
MINIO_ROOT_PASSWORD: secretKey123
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
interval: 5s
|
||||
timeout: 120s
|
||||
retries: 120
|
||||
mc:
|
||||
image: minio/mc:RELEASE.2022-01-07T06-01-38Z
|
||||
entrypoint: bash
|
||||
networks:
|
||||
- e2e
|
||||
command:
|
||||
- -c
|
||||
- mc alias set s3 http://s3:9000 accessKey123 secretKey123 && mc mb s3/dolphinscheduler
|
||||
depends_on:
|
||||
s3:
|
||||
condition: service_healthy
|
||||
|
||||
networks:
|
||||
api-test:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.1.0.0/24
|
||||
gateway: 10.1.0.1
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to 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. Apache Software Foundation (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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dolphinscheduler-api-test</artifactId>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>dolphinscheduler-api-test-core</artifactId>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.test.core;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@UtilityClass
|
||||
public final class Constants {
|
||||
|
||||
/**
|
||||
* backend api url
|
||||
*/
|
||||
public static final String DOLPHINSCHEDULER_API_URL = "http://0.0.0.0:12345/dolphinscheduler";
|
||||
|
||||
/**
|
||||
* backend api request header's content type
|
||||
*/
|
||||
public static final String REQUEST_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
/**
|
||||
* header's session id's key
|
||||
*/
|
||||
public static final String SESSION_ID_KEY = "sessionId";
|
||||
|
||||
/**
|
||||
* simple date format
|
||||
*/
|
||||
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* docker compose default healthy timeout
|
||||
*/
|
||||
public static final Integer DOCKER_COMPOSE_DEFAULT_TIMEOUT = 180;
|
||||
|
||||
public static final String QUESTION_MARK = "?";
|
||||
|
||||
public static final String EQUAL_MARK = "=";
|
||||
|
||||
public static final String AND_MARK = "&";
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.core;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
@Inherited
|
||||
@Testcontainers
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@TestMethodOrder(OrderAnnotation.class)
|
||||
@ExtendWith(DolphinSchedulerExtension.class)
|
||||
public @interface DolphinScheduler {
|
||||
String[] composeFiles();
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to 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. Apache Software Foundation (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.test.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.testcontainers.containers.DockerComposeContainer;
|
||||
import org.testcontainers.containers.wait.strategy.Wait;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback {
|
||||
private final boolean LOCAL_MODE = Objects.equals(System.getProperty("local"), "true");
|
||||
|
||||
private final String SERVICE_NAME = "dolphinscheduler_1";
|
||||
|
||||
private DockerComposeContainer<?> compose;
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
if (!LOCAL_MODE) {
|
||||
compose = createDockerCompose(context);
|
||||
compose.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) {
|
||||
if (compose != null) {
|
||||
compose.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private DockerComposeContainer<?> createDockerCompose(ExtensionContext context) {
|
||||
final Class<?> clazz = context.getRequiredTestClass();
|
||||
final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class);
|
||||
final List<File> files = Stream.of(annotation.composeFiles())
|
||||
.map(it -> DolphinScheduler.class.getClassLoader().getResource(it))
|
||||
.filter(Objects::nonNull)
|
||||
.map(URL::getPath)
|
||||
.map(File::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
compose = new DockerComposeContainer<>(files)
|
||||
.withPull(true)
|
||||
.withTailChildContainers(true)
|
||||
.withLogConsumer(SERVICE_NAME, outputFrame -> LOGGER.info(outputFrame.getUtf8String()))
|
||||
.waitingFor(SERVICE_NAME, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT)));
|
||||
|
||||
return compose;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<Configuration status="DEBUG">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout charset="UTF-8" pattern="%d %c %L [%t] %-5p %x - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
lombok.accessors.fluent=true
|
||||
lombok.log.fieldname=LOGGER
|
||||
lombok.accessors.fluent=true
|
||||
lombok.anyConstructor.addConstructorProperties=true
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-api-test</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<modules>
|
||||
<module>dolphinscheduler-api-test-core</module>
|
||||
<module>dolphinscheduler-api-test-case</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<junit.version>5.7.2</junit.version>
|
||||
<selenium.version>3.141.59</selenium.version>
|
||||
<lombok.version>1.18.24</lombok.version>
|
||||
<assertj-core.version>3.23.1</assertj-core.version>
|
||||
<awaitility.version>4.1.0</awaitility.version>
|
||||
<kotlin.version>1.5.30</kotlin.version>
|
||||
<slf4j-api.version>1.7.36</slf4j-api.version>
|
||||
<log4j-slf4j-impl.version>2.17.2</log4j-slf4j-impl.version>
|
||||
<guava.version>31.0.1-jre</guava.version>
|
||||
<jackson.version>2.13.2</jackson.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j-slf4j-impl.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers-bom</artifactId>
|
||||
<version>1.16.3</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
Loading…
Reference in New Issue