From e6e6d555fd3e6c3af6badf7abc211d65161a8f33 Mon Sep 17 00:00:00 2001 From: Shoothzj Date: Tue, 16 Nov 2021 09:59:57 +0800 Subject: [PATCH] Support to update partition num --- .../pulsar/pulsar_partitioned_topic_api.dart | 17 ++++ .../pulsar_partitioned_topic_basic.dart | 27 ++++++ lib/ui/util/form_util.dart | 88 ++++++++++++++++++- ...ar_partitioned_topic_basic_view_model.dart | 26 ++++++ 4 files changed, 157 insertions(+), 1 deletion(-) diff --git a/lib/api/pulsar/pulsar_partitioned_topic_api.dart b/lib/api/pulsar/pulsar_partitioned_topic_api.dart index af6f733..6321d84 100644 --- a/lib/api/pulsar/pulsar_partitioned_topic_api.dart +++ b/lib/api/pulsar/pulsar_partitioned_topic_api.dart @@ -43,6 +43,23 @@ class PulsarPartitionedTopicAPi { return response.body; } + static Future modifyPartitionTopic(String host, int port, + String tenant, String namespace, String topic, int partitionNum) async { + var url = + 'http://$host:${port.toString()}/admin/v2/persistent/$tenant/$namespace/$topic/partitions'; + var response = await http.post(Uri.parse(url), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: partitionNum.toString()); + if (HttpUtil.abnormal(response.statusCode)) { + log('ErrorCode is ${response.statusCode}, body is ${response.body}'); + throw Exception( + 'ErrorCode is ${response.statusCode}, body is ${response.body}'); + } + return response.body; + } + static Future> getTopics( String host, int port, String tenant, String namespace) async { var url = diff --git a/lib/ui/pulsar/widget/pulsar_partitioned_topic_basic.dart b/lib/ui/pulsar/widget/pulsar_partitioned_topic_basic.dart index defcabd..d7c167e 100644 --- a/lib/ui/pulsar/widget/pulsar_partitioned_topic_basic.dart +++ b/lib/ui/pulsar/widget/pulsar_partitioned_topic_basic.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:paas_dashboard_flutter/generated/l10n.dart'; import 'package:paas_dashboard_flutter/ui/util/exception_util.dart'; +import 'package:paas_dashboard_flutter/ui/util/form_util.dart'; import 'package:paas_dashboard_flutter/ui/util/spinner_util.dart'; import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_partitioned_topic_basic_view_model.dart'; import 'package:provider/provider.dart'; @@ -21,6 +22,7 @@ class PulsarPartitionedTopicBasicWidgetState super.initState(); final vm = Provider.of(context, listen: false); + vm.fetchPartitions(); } @override @@ -33,6 +35,7 @@ class PulsarPartitionedTopicBasicWidgetState } ExceptionUtil.processLoadException(vm, context); ExceptionUtil.processOpException(vm, context); + var formButton = modifyPartitionTopicButton(context); var refreshButton = TextButton(onPressed: () {}, child: Text(S.of(context).refresh)); var body = ListView( @@ -45,8 +48,32 @@ class PulsarPartitionedTopicBasicWidgetState children: [refreshButton], ), ), + Container( + height: 50, + child: ListView( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + children: [ + Text( + 'partition num is ${vm.partitionNum}', + style: new TextStyle(fontSize: 20), + ), + formButton + ], + ), + ), ], ); return body; } + + ButtonStyleButton modifyPartitionTopicButton(BuildContext context) { + var list = [FormFieldDef('New Partition Number')]; + return FormUtil.updateButton1("Topic Partitions", list, context, + (partition) async { + final vm = Provider.of(context, + listen: false); + vm.modifyTopicPartition(vm.topic, int.parse(partition)); + }); + } } diff --git a/lib/ui/util/form_util.dart b/lib/ui/util/form_util.dart index afc9ed8..f1d15c3 100644 --- a/lib/ui/util/form_util.dart +++ b/lib/ui/util/form_util.dart @@ -19,7 +19,7 @@ class FormUtil { throw AssertionError('args not match'); } return createButton(resourceName, formFieldDefList, context, - (list) => callback(list[0], list[1], list[2])); + (list) => callback(list[0], list[1], list[2])); } static ButtonStyleButton createButton2( @@ -95,4 +95,90 @@ class FormUtil { }, child: Text('Create ' + resourceName)); } + + static ButtonStyleButton updateButton3( + String resourceName, + List formFieldDefList, + BuildContext context, + Function(String, String, String) callback) { + if (formFieldDefList.length != 3) { + throw AssertionError('args not match'); + } + return updateButton(resourceName, formFieldDefList, context, + (list) => callback(list[0], list[1], list[2])); + } + + static ButtonStyleButton updateButton2( + String resourceName, + List formFieldDefList, + BuildContext context, + Function(String, String) callback) { + if (formFieldDefList.length != 2) { + throw AssertionError('args not match'); + } + return updateButton(resourceName, formFieldDefList, context, + (list) => callback(list[0], list[1])); + } + + static ButtonStyleButton updateButton1( + String resourceName, + List formFieldDefList, + BuildContext context, + Function(String) callback) { + if (formFieldDefList.length != 1) { + throw AssertionError('args not match'); + } + return updateButton( + resourceName, formFieldDefList, context, (list) => callback(list[0])); + } + + static ButtonStyleButton updateButton( + String resourceName, + List formFieldDefList, + BuildContext context, + Function(List) callback) { + return TextButton( + onPressed: () { + var editControllerList = + formFieldDefList.map((e) => TextEditingController()).toList(); + List formFieldsList = List.generate( + formFieldDefList.length, + (index) => TextFormField( + decoration: InputDecoration( + labelText: formFieldDefList[index].fieldName), + controller: editControllerList[index], + )); + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + scrollable: true, + title: Text(resourceName + ' Form'), + content: Form( + child: Column( + children: formFieldsList, + )), + actions: [ + ElevatedButton( + child: Text(CREATE), + onPressed: () { + var list = editControllerList + .map((e) => e.value.text) + .toList(); + callback(list); + Navigator.of(context).pop(); + }, + ), + ElevatedButton( + child: Text(CANCEL), + onPressed: () { + Navigator.of(context).pop(); + }, + ) + ], + ); + }); + }, + child: Text('Update ' + resourceName)); + } } diff --git a/lib/vm/pulsar/pulsar_partitioned_topic_basic_view_model.dart b/lib/vm/pulsar/pulsar_partitioned_topic_basic_view_model.dart index efe37ec..0387d10 100644 --- a/lib/vm/pulsar/pulsar_partitioned_topic_basic_view_model.dart +++ b/lib/vm/pulsar/pulsar_partitioned_topic_basic_view_model.dart @@ -1,3 +1,4 @@ +import 'package:paas_dashboard_flutter/api/pulsar/pulsar_partitioned_topic_api.dart'; import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart'; import 'package:paas_dashboard_flutter/module/pulsar/pulsar_tenant.dart'; import 'package:paas_dashboard_flutter/module/pulsar/pulsar_topic.dart'; @@ -9,6 +10,7 @@ class PulsarPartitionedTopicBasicViewModel extends BaseLoadViewModel { final TenantResp tenantResp; final NamespaceResp namespaceResp; final TopicResp topicResp; + String partitionNum = ""; PulsarPartitionedTopicBasicViewModel(this.pulsarInstancePo, this.tenantResp, this.namespaceResp, this.topicResp); @@ -45,4 +47,28 @@ class PulsarPartitionedTopicBasicViewModel extends BaseLoadViewModel { String get topic { return this.topicResp.topicName; } + + Future fetchPartitions() async { + try { + final results = await PulsarPartitionedTopicAPi.getDetails( + host, port, tenant, namespace, topic); + partitionNum = results.length.toString(); + loadSuccess(); + } on Exception catch (e) { + loadException = e; + loading = false; + } + notifyListeners(); + } + + Future modifyTopicPartition(String topic, int partition) async { + try { + await PulsarPartitionedTopicAPi.modifyPartitionTopic( + host, port, tenant, namespace, topic, partition); + await fetchPartitions(); + } on Exception catch (e) { + opException = e; + notifyListeners(); + } + } }