Skip to content

Commit e412286

Browse files
authored
[Fix-4530-1.2] Fix resolve pagination error when changing pages on the Registry (#4542)
1 parent f6e6a4f commit e412286

File tree

7 files changed

+153
-53
lines changed

7 files changed

+153
-53
lines changed

.github/workflows/backend.yaml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,58 @@ jobs:
244244
- name: Init k3s
245245
uses: nolar/setup-k3d-k3s@v1
246246
with:
247-
version: v1.27.16+k3s1
247+
version: v1.35.2+k3s1
248248
k3d-args: -s 1 --network dinky_net --api-port 172.28.0.1:6550
249249
k3d-tag: v5.7.5
250-
- name: Get k3s kube config
251-
run: k3d kubeconfig get --all && mkdir ./kube && k3d kubeconfig get --all > ./kube/k3s.yaml && sed -i 's/0.0.0.0/172.28.0.1/g' ./kube/k3s.yaml
252250
- name: Init k8s RBAC and namespace
253251
run: |
254252
kubectl create namespace dinky
255253
kubectl create serviceaccount dinky -n dinky
256254
kubectl create clusterrolebinding flink-role-binding-dinky --clusterrole=edit --serviceaccount=dinky:dinky
255+
cat <<EOF | kubectl apply -f -
256+
apiVersion: rbac.authorization.k8s.io/v1
257+
kind: ClusterRole
258+
metadata:
259+
name: dinky-node-reader
260+
rules:
261+
- apiGroups: [""]
262+
resources: ["nodes"]
263+
verbs: ["get", "list", "watch"]
264+
---
265+
apiVersion: rbac.authorization.k8s.io/v1
266+
kind: ClusterRoleBinding
267+
metadata:
268+
name: dinky-node-reader-binding
269+
roleRef:
270+
apiGroup: rbac.authorization.k8s.io
271+
kind: ClusterRole
272+
name: dinky-node-reader
273+
subjects:
274+
- kind: ServiceAccount
275+
name: dinky
276+
namespace: dinky
277+
EOF
278+
mkdir ./kube
279+
cat <<EOF > ./kube/k3s.yaml
280+
apiVersion: v1
281+
kind: Config
282+
clusters:
283+
- name: k3d-default
284+
cluster:
285+
server: https://172.28.0.1:6550
286+
insecure-skip-tls-verify: true
287+
users:
288+
- name: dinky
289+
user:
290+
token: $(kubectl create token dinky -n dinky)
291+
contexts:
292+
- name: dinky
293+
context:
294+
cluster: k3d-default
295+
namespace: dinky
296+
user: dinky
297+
current-context: dinky
298+
EOF
257299
- name: Init k3s main images
258300
run: |
259301
docker exec k3d-k3s-default-server-0 crictl pull library/busybox:latest

dinky-admin/src/main/resources/mapper/DocumentMapper.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
<if test='param.subtype!=null and param.subtype!=""'>
4747
and a.subtype = #{param.subtype}
4848
</if>
49+
<if test='param.enabled != null and param.enabled != ""'>
50+
and a.enabled =
51+
<choose>
52+
<when test='param.enabled == true or param.enabled == 1 or param.enabled == "true" or param.enabled == "1"'>1</when>
53+
<otherwise>0</otherwise>
54+
</choose>
55+
</if>
4956
<if test='param.version!=null and param.version!=""'>
5057
and a.version = #{param.version}
5158
</if>

dinky-gateway/src/main/java/org/dinky/gateway/kubernetes/KubernetesGateway.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@
4141
import org.apache.flink.kubernetes.KubernetesClusterClientFactory;
4242
import org.apache.flink.kubernetes.KubernetesClusterDescriptor;
4343
import org.apache.flink.kubernetes.configuration.KubernetesConfigOptions;
44-
import org.apache.flink.kubernetes.kubeclient.Fabric8FlinkKubeClient;
45-
import org.apache.flink.kubernetes.kubeclient.FlinkKubeClient;
4644
import org.apache.flink.python.PythonOptions;
4745

48-
import java.lang.reflect.Method;
46+
import java.lang.reflect.InvocationTargetException;
4947
import java.util.Collections;
5048
import java.util.Map;
5149
import java.util.UUID;
@@ -55,7 +53,6 @@
5553
import cn.hutool.core.io.FileUtil;
5654
import cn.hutool.core.lang.Assert;
5755
import cn.hutool.core.text.StrFormatter;
58-
import cn.hutool.core.util.ReflectUtil;
5956
import cn.hutool.core.util.StrUtil;
6057
import io.fabric8.kubernetes.api.model.Pod;
6158
import lombok.Data;
@@ -224,26 +221,37 @@ public TestResult test() {
224221
// Test mode no jobName, use uuid .
225222
addConfigParas(KubernetesConfigOptions.CLUSTER_ID, UUID.randomUUID().toString());
226223
initConfig();
227-
FlinkKubeClient client = k8sClientHelper.getClient();
228-
if (client instanceof Fabric8FlinkKubeClient) {
229-
Object internalClient = ReflectUtil.getFieldValue(client, "internalClient");
230-
Method method = ReflectUtil.getMethod(internalClient.getClass(), "getVersion");
231-
Object versionInfo = method.invoke(internalClient);
232-
logger.info(
233-
"k8s cluster link successful ; k8s version: {} ; platform: {}",
234-
ReflectUtil.getFieldValue(versionInfo, "gitVersion"),
235-
ReflectUtil.getFieldValue(versionInfo, "platform"));
236-
}
224+
String namespace = configuration.get(KubernetesConfigOptions.NAMESPACE);
225+
k8sClientHelper.getKubernetesClient().pods().inNamespace(namespace).list();
226+
logger.info("k8s cluster link successful ; namespace: {}", namespace);
237227
return TestResult.success();
238228
} catch (Exception e) {
239229
logger.error(Status.GATEWAY_KUBERNETES_TEST_FAILED.getMessage(), e);
230+
String errorDetail = extractTestErrorDetail(e);
240231
return TestResult.fail(
241-
StrFormatter.format("{}:{}", Status.GATEWAY_KUBERNETES_TEST_FAILED.getMessage(), e.getMessage()));
232+
StrFormatter.format("{} {}", Status.GATEWAY_KUBERNETES_TEST_FAILED.getMessage(), errorDetail));
242233
} finally {
243234
close();
244235
}
245236
}
246237

238+
static String extractTestErrorDetail(Throwable throwable) {
239+
Throwable rootCause = throwable;
240+
while (rootCause instanceof InvocationTargetException
241+
&& ((InvocationTargetException) rootCause).getTargetException() != null) {
242+
rootCause = ((InvocationTargetException) rootCause).getTargetException();
243+
}
244+
while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
245+
rootCause = rootCause.getCause();
246+
}
247+
248+
String message = rootCause.getMessage();
249+
if (StringUtils.isBlank(message)) {
250+
return rootCause.getClass().getName();
251+
}
252+
return StrFormatter.format("{}: {}", rootCause.getClass().getName(), message);
253+
}
254+
247255
@Override
248256
public void killCluster() {
249257
log.info("Start kill cluster: " + config.getFlinkConfig().getJobName());
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
*
3+
* Licensed to the Apache Software Foundation (ASF) under one or more
4+
* contributor license agreements. See the NOTICE file distributed with
5+
* this work for additional information regarding copyright ownership.
6+
* The ASF licenses this file to You under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance with
8+
* the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
package org.dinky.gateway.kubernetes;
21+
22+
import static org.junit.Assert.assertEquals;
23+
24+
import java.lang.reflect.InvocationTargetException;
25+
26+
import org.junit.Test;
27+
28+
public class KubernetesGatewayTest {
29+
30+
@Test
31+
public void testExtractTestErrorDetailUnwrapsInvocationTargetException() {
32+
IllegalStateException rootCause = new IllegalStateException("connection refused");
33+
InvocationTargetException invocationTargetException = new InvocationTargetException(rootCause);
34+
35+
String errorDetail = KubernetesGateway.extractTestErrorDetail(invocationTargetException);
36+
37+
assertEquals("java.lang.IllegalStateException: connection refused", errorDetail);
38+
}
39+
40+
@Test
41+
public void testExtractTestErrorDetailFallsBackToClassName() {
42+
NullPointerException rootCause = new NullPointerException();
43+
44+
String errorDetail = KubernetesGateway.extractTestErrorDetail(rootCause);
45+
46+
assertEquals("java.lang.NullPointerException", errorDetail);
47+
}
48+
}

dinky-web/pom.xml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
<npmVersion>10.5.0</npmVersion>
5252
<pnpmVersion>9.15.4</pnpmVersion>
5353
<!-- 国内node下载加速 -->
54-
<!-- <nodeDownloadRoot>https://mirrors.huaweicloud.com/nodejs/</nodeDownloadRoot>-->
55-
<!-- <npmDownloadRoot>https://repo.huaweicloud.com/npm-software/</npmDownloadRoot>-->
54+
<!-- <nodeDownloadRoot>https://mirrors.huaweicloud.com/nodejs/</nodeDownloadRoot>-->
55+
<!-- <npmDownloadRoot>https://repo.huaweicloud.com/npm-software/</npmDownloadRoot>-->
5656
</configuration>
5757
<executions>
5858
<execution>
@@ -61,24 +61,24 @@
6161
<goal>install-node-and-pnpm</goal>
6262
</goals>
6363
</execution>
64-
<execution>
65-
<id>install</id>
66-
<goals>
67-
<goal>pnpm</goal>
68-
</goals>
69-
<configuration>
70-
<arguments>install --registry ${npm-registry-repo}</arguments>
71-
</configuration>
72-
</execution>
73-
<execution>
74-
<id>build</id>
75-
<goals>
76-
<goal>pnpm</goal>
77-
</goals>
78-
<configuration>
79-
<arguments>run build</arguments>
80-
</configuration>
81-
</execution>
64+
<execution>
65+
<id>install</id>
66+
<goals>
67+
<goal>pnpm</goal>
68+
</goals>
69+
<configuration>
70+
<arguments>install --registry ${npm-registry-repo}</arguments>
71+
</configuration>
72+
</execution>
73+
<execution>
74+
<id>build</id>
75+
<goals>
76+
<goal>pnpm</goal>
77+
</goals>
78+
<configuration>
79+
<arguments>run build</arguments>
80+
</configuration>
81+
</execution>
8282
</executions>
8383
</plugin>
8484
</plugins>

dinky-web/src/pages/RegCenter/Document/components/DocumentProTable/index.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,12 @@ const DocumentTableList: React.FC = () => {
117117
title: l('rc.doc.functionType'),
118118
sorter: true,
119119
dataIndex: 'type',
120-
filterMultiple: true,
121-
filters: true,
122120
valueEnum: DOCUMENT_TYPE_ENUMS
123121
},
124122
{
125123
title: l('rc.doc.subFunctionType'),
126124
sorter: true,
127125
dataIndex: 'subtype',
128-
filters: true,
129-
filterMultiple: true,
130126
renderFormItem: (item, { type }, form) => {
131127
const currentType = form.getFieldValue('type');
132128
let options = currentType === DOCUMENT_TYPE_ENUMS.FUN_UDF.value ? FUNCTION_TYPES : JOB_TYPE;
@@ -139,8 +135,6 @@ const DocumentTableList: React.FC = () => {
139135
title: l('rc.doc.category'),
140136
sorter: true,
141137
dataIndex: 'category',
142-
filterMultiple: true,
143-
filters: true,
144138
valueEnum: DOCUMENT_CATEGORY_ENUMS
145139
},
146140
{
@@ -172,11 +166,11 @@ const DocumentTableList: React.FC = () => {
172166
{
173167
title: l('global.table.isEnable'),
174168
dataIndex: 'enabled',
175-
hideInSearch: true,
176-
filters: STATUS_MAPPING(),
177-
filterMultiple: false,
178169
hideInDescriptions: true,
179-
valueEnum: STATUS_ENUM(),
170+
valueType: 'select',
171+
valueEnum: Object.fromEntries(
172+
STATUS_MAPPING().map(item => [item.value, { text: item.text, status: item.value === 1 ? 'Success' : 'Error' }])
173+
),
180174
render: (_, record) => {
181175
return (
182176
<EnableSwitchBtn

e2e_test/tools/env.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ def addStandaloneCluster(session: Session) -> int:
3333

3434
def addApplicationCluster(session: Session, params: dict) -> Optional[int]:
3535
name = params['name']
36-
test_connection_yarn_resp = session.post(url("api/clusterConfiguration/testConnect"), json=params)
37-
assertRespOk(test_connection_yarn_resp, "Test yarn connectivity")
38-
test_connection_yarn_resp = session.put(url("api/clusterConfiguration/saveOrUpdate"), json=params)
39-
assertRespOk(test_connection_yarn_resp, "Add Yarn Application Cluster")
36+
cluster_type = params["type"]
37+
test_connection_resp = session.post(url("api/clusterConfiguration/testConnect"), json=params)
38+
assertRespOk(test_connection_resp, f"Test {cluster_type} connectivity")
39+
save_cluster_resp = session.put(url("api/clusterConfiguration/saveOrUpdate"), json=params)
40+
assertRespOk(save_cluster_resp, f"Add {cluster_type} cluster")
4041
get_app_list = session.get(url(f"api/clusterConfiguration/list?keyword={name}"), json=params)
41-
assertRespOk(get_app_list, "Get Yarn Application Cluster")
42+
assertRespOk(get_app_list, f"Get {cluster_type} cluster")
4243
for data in get_app_list.json()["data"]:
4344
if data["name"] == name:
4445
return data['id']

0 commit comments

Comments
 (0)