You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2020/10/10 10:07:06 UTC

[apisix-dashboard] branch feat-upstream updated: feat(Upstream): debug api

This is an automated email from the ASF dual-hosted git repository.

juzhiyuan pushed a commit to branch feat-upstream
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git


The following commit(s) were added to refs/heads/feat-upstream by this push:
     new d274033  feat(Upstream): debug api
d274033 is described below

commit d2740331b54a44f84485c140e7b2a0c1413d61c3
Author: juzhiyuan <ju...@apache.org>
AuthorDate: Sat Oct 10 18:06:34 2020 +0800

    feat(Upstream): debug api
---
 src/components/Upstream/UpstreamForm.tsx  |  5 +-
 src/pages/Upstream/Create.tsx             | 33 +++---------
 src/pages/Upstream/components/Preview.tsx | 33 ------------
 src/pages/Upstream/components/Step1.tsx   | 86 +++++++++----------------------
 src/pages/Upstream/service.ts             |  8 +--
 src/pages/Upstream/transform.ts           | 56 +++++++-------------
 src/pages/Upstream/typing.d.ts            | 26 ++++------
 7 files changed, 66 insertions(+), 181 deletions(-)

diff --git a/src/components/Upstream/UpstreamForm.tsx b/src/components/Upstream/UpstreamForm.tsx
index fe6df1e..bf67be0 100644
--- a/src/components/Upstream/UpstreamForm.tsx
+++ b/src/components/Upstream/UpstreamForm.tsx
@@ -2,6 +2,7 @@ import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
 import { Button, Col, Divider, Form, Input, InputNumber, Row, Select, Switch } from 'antd';
 import React, { useEffect, useState } from 'react';
 import { useIntl } from 'umi';
+import type { FormInstance } from 'antd/lib/form';
 
 import { PanelSection } from '@api7-dashboard/ui';
 
@@ -33,6 +34,7 @@ enum HashKey {
 type Upstream = {};
 
 type Props = {
+  form: FormInstance;
   upstream?: Upstream;
   id?: string;
 };
@@ -52,9 +54,8 @@ const timeoutFields = [
   },
 ];
 
-const UpstreamForm: React.FC<Props> = ({ id }) => {
+const UpstreamForm: React.FC<Props> = ({ form, id }) => {
   const [readonly] = useState(false);
-  const [form] = Form.useForm();
   const { formatMessage } = useIntl();
 
   useEffect(() => {
diff --git a/src/pages/Upstream/Create.tsx b/src/pages/Upstream/Create.tsx
index 5c6f190..3199203 100644
--- a/src/pages/Upstream/Create.tsx
+++ b/src/pages/Upstream/Create.tsx
@@ -22,45 +22,30 @@ import { history, useIntl } from 'umi';
 import ActionBar from '@/components/ActionBar';
 
 import Step1 from './components/Step1';
-import Preview from './components/Preview';
 import { fetchOne, create, update } from './service';
-import { transformRequest, transformResponse } from './transform';
+import { transformRequest } from './transform';
 
 const Page: React.FC = (props) => {
   const [step, setStep] = useState(1);
-  const [active, setActive] = useState(false);
-  const [passive, setPassive] = useState(false);
   const [form1] = Form.useForm();
   const { formatMessage } = useIntl();
 
-  const onChange = (checkActive: boolean, checkPassive: boolean) => {
-    setActive(checkActive);
-    setPassive(checkPassive);
-  };
-
   useEffect(() => {
     const { id } = (props as any).match.params;
 
     if (id) {
       fetchOne(id).then((data) => {
-        const formData = transformResponse(data);
-        form1.setFieldsValue(formData);
-        if (formData.active) {
-          setActive(true);
-        }
-        if (formData.passive) {
-          setPassive(true);
-        }
+        form1.setFieldsValue(data.data);
       });
     }
   }, []);
 
   const onSubmit = () => {
-    const data = transformRequest(form1.getFieldsValue() as UpstreamModule.FormFieldsType);
+    const data = transformRequest(form1.getFieldsValue());
     if (!data) {
       // TODO: i18n
-      notification.error({message: "请检查配置"})
-      return
+      notification.error({ message: '请检查配置' });
+      return;
     }
 
     const { id } = (props as any).match.params;
@@ -97,12 +82,8 @@ const Page: React.FC = (props) => {
             <Steps.Step title={formatMessage({ id: 'upstream.create.preview' })} />
           </Steps>
 
-          {step === 1 && (
-            <Step1 form={form1} isActive={active} onChange={onChange} isPassive={passive} />
-          )}
-          {step === 2 && (
-            <Preview form1={form1} isActive={active} onChange={onChange} isPassive={passive} />
-          )}
+          {step === 1 && <Step1 form={form1} />}
+          {step === 2 && <Step1 form={form1} disabled />}
         </Card>
       </PageContainer>
       <ActionBar step={step} lastStep={2} onChange={onStepChange} />
diff --git a/src/pages/Upstream/components/Preview.tsx b/src/pages/Upstream/components/Preview.tsx
deleted file mode 100644
index f73cf16..0000000
--- a/src/pages/Upstream/components/Preview.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import { FormInstance } from 'antd/lib/form';
-
-import Step1 from './Step1';
-
-type Props = {
-  form1: FormInstance;
-  isActive: boolean;
-  isPassive: boolean;
-  onChange(a: boolean, p: boolean): void;
-};
-
-const Page: React.FC<Props> = ({ form1, isActive, onChange, isPassive }) => (
-  <Step1 form={form1} disabled isActive={isActive} onChange={onChange} isPassive={isPassive} />
-);
-
-export default Page;
diff --git a/src/pages/Upstream/components/Step1.tsx b/src/pages/Upstream/components/Step1.tsx
index e1a457c..421a526 100644
--- a/src/pages/Upstream/components/Step1.tsx
+++ b/src/pages/Upstream/components/Step1.tsx
@@ -24,76 +24,36 @@ import UpstreamForm from '@/components/Upstream';
 type Props = {
   form: FormInstance;
   disabled?: boolean;
-  isActive: boolean;
-  isPassive: boolean;
-  onChange(checkActive: boolean, checkPassive: boolean): void;
 };
 
-const initialValues = {
-  name: '',
-  description: '',
-  type: 'roundrobin',
-  upstreamHostList: [{} as UpstreamModule.UpstreamHost],
-  timeout: {
-    connect: 6000,
-    send: 6000,
-    read: 6000,
-  },
-  active: false,
-  passive: false,
-  checks: {
-    active: {
-      timeout: 5,
-      http_path: '',
-      host: '',
-      healthy: {
-        interval: 2,
-        successes: 1,
-      },
-      unhealthy: {
-        interval: 1,
-        http_failures: 2,
-      },
-      req_headers: [''],
-    },
-    passive: {
-      healthy: {
-        http_statuses: [undefined],
-        successes: 3,
-      },
-      unhealthy: {
-        http_statuses: [undefined],
-        http_failures: 3,
-        tcp_failures: 3,
-      },
-    },
-  },
-};
+const initialValues = {};
 
 const Step1: React.FC<Props> = ({ form, disabled }) => {
   const { formatMessage } = useIntl();
 
   return (
-    <Form labelCol={{ span: 3 }} form={form} initialValues={initialValues}>
-      <Form.Item
-        label={formatMessage({ id: 'upstream.step.name' })}
-        name="name"
-        rules={[{ required: true }]}
-        extra={formatMessage({ id: 'upstream.step.name.should.unique' })}
-      >
-        <Input
-          placeholder={formatMessage({ id: 'upstream.step.input.upstream.name' })}
-          disabled={disabled}
-        />
-      </Form.Item>
-      <Form.Item label={formatMessage({ id: 'upstream.step.description' })} name="desc">
-        <Input.TextArea
-          placeholder={formatMessage({ id: 'upstream.step.input.description' })}
-          disabled={disabled}
-        />
-      </Form.Item>
-      <UpstreamForm />
-    </Form>
+    <>
+      <Form labelCol={{ span: 3 }} form={form} initialValues={initialValues}>
+        <Form.Item
+          label={formatMessage({ id: 'upstream.step.name' })}
+          name="name"
+          rules={[{ required: true }]}
+          extra={formatMessage({ id: 'upstream.step.name.should.unique' })}
+        >
+          <Input
+            placeholder={formatMessage({ id: 'upstream.step.input.upstream.name' })}
+            disabled={disabled}
+          />
+        </Form.Item>
+        <Form.Item label={formatMessage({ id: 'upstream.step.description' })} name="desc">
+          <Input.TextArea
+            placeholder={formatMessage({ id: 'upstream.step.input.description' })}
+            disabled={disabled}
+          />
+        </Form.Item>
+      </Form>
+      <UpstreamForm form={form} />
+    </>
   );
 };
 
diff --git a/src/pages/Upstream/service.ts b/src/pages/Upstream/service.ts
index 1474e76..57f9ca1 100644
--- a/src/pages/Upstream/service.ts
+++ b/src/pages/Upstream/service.ts
@@ -18,13 +18,13 @@ import { request } from 'umi';
 
 export const fetchList = () => {
   // TODO: Use Cache and search on local
-  return request<Res<ResListData<UpstreamModule.FormFieldsType>>>('/upstreams').then(({ data }) => ({
+  return request<Res<ResListData<UpstreamModule.RequestBody>>>('/upstreams').then(({ data }) => ({
     data: data.rows,
     total: data.total_size,
-  }))
-}
+  }));
+};
 
-export const fetchOne = (id: string) => request(`/upstreams/${id}`);
+export const fetchOne = (id: string) => request<Res<any>>(`/upstreams/${id}`);
 
 export const create = (data: UpstreamModule.RequestBody) =>
   request('/upstreams', {
diff --git a/src/pages/Upstream/transform.ts b/src/pages/Upstream/transform.ts
index 38880dc..0a9863c 100644
--- a/src/pages/Upstream/transform.ts
+++ b/src/pages/Upstream/transform.ts
@@ -1,4 +1,4 @@
-import { pickBy, identity } from "lodash"
+import { pickBy, identity, omit } from 'lodash';
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -16,58 +16,40 @@ import { pickBy, identity } from "lodash"
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-export const transformRequest = (formData: UpstreamModule.FormFieldsType): UpstreamModule.RequestBody | undefined => {
-  const data = pickBy(formData, identity) as UpstreamModule.FormFieldsType
-  const { type, hash_on, key, k8s_deployment_info, nodes, pass_host, upstream_host } = data
-
+export const transformRequest = (
+  formData: UpstreamModule.RequestBody,
+): UpstreamModule.RequestBody | undefined => {
+  let data = pickBy(formData, identity) as UpstreamModule.RequestBody;
+  const { type, hash_on, key, k8s_deployment_info, nodes, pass_host, upstream_host } = data;
+  data.checks = pickBy(data.checks, identity);
+  if (Object.keys(data.checks).length === 0) {
+    data = omit(data, 'checks');
+  }
   if (nodes && k8s_deployment_info) {
-    return undefined
+    return undefined;
   }
 
   if (!nodes && !k8s_deployment_info) {
-    return undefined
+    return undefined;
   }
 
   if (type === 'chash') {
     if (!hash_on) {
-      return undefined
+      return undefined;
     }
 
-    if (hash_on !== "consumer" && !key) {
-      return undefined
+    if (hash_on !== 'consumer' && !key) {
+      return undefined;
     }
   }
 
   if (pass_host === 'rewrite' && !upstream_host) {
-    return undefined
+    return undefined;
   }
 
   if (nodes) {
-    const nodeObjects = {}
-    nodes.forEach(({ host, port, weight }) => {
-      nodeObjects[`${host}:${port}`] = weight
-    })
-    return {
-      ...data,
-      nodes: nodeObjects
-    }
+    return data;
   }
 
-  return undefined
-}
-
-export const transformResponse = (data: UpstreamModule.ResponseBody): UpstreamModule.FormFieldsType => {
-  return {
-    ...data,
-    active: Boolean(data.checks),
-    passive: Boolean(data.checks?.passive),
-    nodes: Object.entries(data.nodes || {}).map(([key, weight]) => {
-      const [host, port] = key.split(':')
-      return {
-        host,
-        port: Number(port),
-        weight
-      }
-    })
-  }
-}
+  return undefined;
+};
diff --git a/src/pages/Upstream/typing.d.ts b/src/pages/Upstream/typing.d.ts
index 9dd6c82..883ae6b 100644
--- a/src/pages/Upstream/typing.d.ts
+++ b/src/pages/Upstream/typing.d.ts
@@ -15,12 +15,12 @@
  * limitations under the License.
  */
 declare namespace UpstreamModule {
-  type Node = Record<string, number>
+  type Node = UpstreamHost[];
 
-  type Timeout = Record<"connect" | "send" | "read", number>
+  type Timeout = Record<'connect' | 'send' | 'read', number>;
 
   type HealthCheck = {
-    active: {
+    active?: {
       timeout?: number;
       http_path: string;
       host: string;
@@ -45,7 +45,7 @@ declare namespace UpstreamModule {
         tcp_failures: number;
       };
     };
-  }
+  };
 
   type UpstreamHost = {
     host: string;
@@ -54,8 +54,8 @@ declare namespace UpstreamModule {
   };
 
   type RequestBody = {
-    type: "roundrobin" | "chash" | "ewma";
-    nodes?: Node;
+    type: 'roundrobin' | 'chash' | 'ewma';
+    nodes?: Node[];
     k8s_deployment_info?: {
       namespace: string;
       deploy_name: string;
@@ -63,7 +63,7 @@ declare namespace UpstreamModule {
       backend_type: string;
       port: number;
     };
-    hash_on?: "vars" | "header" | "cookie" | "consumer";
+    hash_on?: 'vars' | 'header' | 'cookie' | 'consumer';
     key?: string;
     checks?: HealthCheck;
     retries?: number;
@@ -71,16 +71,10 @@ declare namespace UpstreamModule {
     timeout?: Timeout;
     name?: string;
     desc?: string;
-    pass_host?: "pass" | "node" | "rewrite";
+    pass_host?: 'pass' | 'node' | 'rewrite';
     upstream_host: UpstreamHost[];
-  }
+  };
 
   // TODO: typing
-  type ResponseBody = {} & RequestBody
-
-  type FormFieldsType = {
-    active: boolean;
-    passive: boolean;
-    nodes: UpstreamHost[];
-  } & Omit<RequestBody, 'nodes'>
+  type ResponseBody = {} & RequestBody;
 }