@platformatic/kafka 2.2.3 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/apis/admin/create-topics-v7.js +1 -0
- package/dist/apis/callbacks.d.ts +1 -3
- package/dist/apis/callbacks.js +26 -11
- package/dist/clients/admin/admin.js +330 -356
- package/dist/clients/base/base.js +8 -1
- package/dist/clients/consumer/consumer.js +92 -4
- package/dist/clients/consumer/messages-stream.js +12 -1
- package/dist/clients/consumer/utils.d.ts +1 -0
- package/dist/clients/consumer/utils.js +6 -0
- package/dist/clients/producer/producer.js +67 -13
- package/dist/clients/serde.d.ts +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +6 -0
- package/dist/network/connection-pool.js +9 -1
- package/dist/protocol/reader.js +4 -3
- package/dist/registries/abstract.d.ts +2 -2
- package/dist/registries/confluent-schema-registry.d.ts +1 -1
- package/dist/registries/confluent-schema-registry.js +3 -0
- package/dist/typescript-4/dist/apis/callbacks.d.ts +1 -3
- package/dist/typescript-4/dist/clients/consumer/utils.d.ts +2 -1
- package/dist/typescript-4/dist/clients/serde.d.ts +1 -1
- package/dist/typescript-4/dist/errors.d.ts +2 -0
- package/dist/typescript-4/dist/registries/abstract.d.ts +2 -2
- package/dist/typescript-4/dist/registries/confluent-schema-registry.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
|
@@ -374,7 +374,7 @@ export class Admin extends Base {
|
|
|
374
374
|
}
|
|
375
375
|
#handleNotControllerError(error, value, callback) {
|
|
376
376
|
if (error && error?.findBy?.('apiCode', 41)) {
|
|
377
|
-
this
|
|
377
|
+
this[kMetadata]({ topics: [], forceUpdate: true }, (metadataError, metadata) => {
|
|
378
378
|
/* c8 ignore next 4 - Hard to test */
|
|
379
379
|
if (metadataError) {
|
|
380
380
|
callback(metadataError);
|
|
@@ -407,7 +407,7 @@ export class Admin extends Base {
|
|
|
407
407
|
});
|
|
408
408
|
}, (error, metadata) => {
|
|
409
409
|
if (error) {
|
|
410
|
-
deduplicateCallback(error);
|
|
410
|
+
deduplicateCallback(new MultipleErrors('Listing topics failed.', [error]));
|
|
411
411
|
return;
|
|
412
412
|
}
|
|
413
413
|
const topics = new Set();
|
|
@@ -460,7 +460,7 @@ export class Admin extends Base {
|
|
|
460
460
|
});
|
|
461
461
|
}, (error, response) => {
|
|
462
462
|
if (error) {
|
|
463
|
-
deduplicateCallback(error);
|
|
463
|
+
deduplicateCallback(new MultipleErrors('Creating topics failed.', [error]));
|
|
464
464
|
return;
|
|
465
465
|
}
|
|
466
466
|
const created = [];
|
|
@@ -497,7 +497,13 @@ export class Admin extends Base {
|
|
|
497
497
|
});
|
|
498
498
|
});
|
|
499
499
|
});
|
|
500
|
-
},
|
|
500
|
+
}, (error, response) => {
|
|
501
|
+
if (error) {
|
|
502
|
+
callback(new MultipleErrors('Deleting topics failed.', [error]));
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
deduplicateCallback(null, response);
|
|
506
|
+
}, 0);
|
|
501
507
|
}, error => callback(error));
|
|
502
508
|
}
|
|
503
509
|
#createPartitions(options, callback) {
|
|
@@ -529,13 +535,14 @@ export class Admin extends Base {
|
|
|
529
535
|
});
|
|
530
536
|
}
|
|
531
537
|
#listGroups(options, callback) {
|
|
532
|
-
|
|
533
|
-
this[kMetadata]({ topics: [] }, (error, metadata) => {
|
|
538
|
+
this[kMetadata]({ topics: [], forceUpdate: true }, (error, metadata) => {
|
|
534
539
|
if (error) {
|
|
535
540
|
callback(error);
|
|
536
541
|
return;
|
|
537
542
|
}
|
|
538
|
-
runConcurrentCallbacks('Listing groups failed.',
|
|
543
|
+
runConcurrentCallbacks('Listing groups failed.',
|
|
544
|
+
// metadata must be defined as error was undefined
|
|
545
|
+
metadata.brokers, ([, broker], concurrentCallback) => {
|
|
539
546
|
this[kGetConnection](broker, (error, connection) => {
|
|
540
547
|
if (error) {
|
|
541
548
|
concurrentCallback(error);
|
|
@@ -573,45 +580,42 @@ export class Admin extends Base {
|
|
|
573
580
|
});
|
|
574
581
|
}
|
|
575
582
|
#describeGroups(options, callback) {
|
|
576
|
-
this[
|
|
577
|
-
if (error) {
|
|
578
|
-
callback(error);
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
583
|
+
this[kPerformWithRetry]('describeGroups', retryCallback => {
|
|
581
584
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: options.groups }, (error, coordinators) => {
|
|
582
585
|
if (error) {
|
|
583
|
-
|
|
586
|
+
// FindCoordinator already retried some times so no retry again
|
|
587
|
+
callback(new MultipleErrors('Describing groups failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
584
588
|
return;
|
|
585
589
|
}
|
|
586
|
-
// Group the groups by coordinator
|
|
587
590
|
const coordinatorsMap = new Map();
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
591
|
+
// coordinators must be defined as error was undefined
|
|
592
|
+
for (const coordinator of coordinators) {
|
|
593
|
+
let coordinatorAggregate = coordinatorsMap.get(coordinator.nodeId);
|
|
594
|
+
if (!coordinatorAggregate) {
|
|
595
|
+
coordinatorAggregate = { host: coordinator.host, port: coordinator.port, groups: [] };
|
|
596
|
+
coordinatorsMap.set(coordinator.nodeId, coordinatorAggregate);
|
|
593
597
|
}
|
|
594
|
-
|
|
598
|
+
coordinatorAggregate.groups.push(coordinator.key);
|
|
595
599
|
}
|
|
596
|
-
runConcurrentCallbacks('Describing groups failed.', coordinatorsMap, (
|
|
597
|
-
this[
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
600
|
+
runConcurrentCallbacks('Describing groups failed.', coordinatorsMap.values(), (coordinator, concurrentCallback) => {
|
|
601
|
+
this[kPerformWithRetry]('describeGroupsOnCoordinator', retryCallback => {
|
|
602
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
603
|
+
if (error) {
|
|
604
|
+
retryCallback(error);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
603
607
|
this[kGetApi]('DescribeGroups', (error, api) => {
|
|
604
608
|
if (error) {
|
|
605
609
|
retryCallback(error);
|
|
606
610
|
return;
|
|
607
611
|
}
|
|
608
|
-
api(connection, groups, options.includeAuthorizedOperations ?? false, retryCallback);
|
|
612
|
+
api(connection, coordinator.groups, options.includeAuthorizedOperations ?? false, retryCallback);
|
|
609
613
|
});
|
|
610
|
-
}
|
|
611
|
-
});
|
|
614
|
+
});
|
|
615
|
+
}, concurrentCallback, 0);
|
|
612
616
|
}, (error, results) => {
|
|
613
617
|
if (error) {
|
|
614
|
-
|
|
618
|
+
retryCallback(error);
|
|
615
619
|
return;
|
|
616
620
|
}
|
|
617
621
|
const groups = new Map();
|
|
@@ -655,59 +659,58 @@ export class Admin extends Base {
|
|
|
655
659
|
groups.set(group.id, group);
|
|
656
660
|
}
|
|
657
661
|
}
|
|
658
|
-
|
|
662
|
+
retryCallback(null, groups);
|
|
659
663
|
});
|
|
660
664
|
});
|
|
661
|
-
});
|
|
665
|
+
}, callback, 0);
|
|
662
666
|
}
|
|
663
667
|
#deleteGroups(options, callback) {
|
|
664
|
-
this[
|
|
665
|
-
if (error) {
|
|
666
|
-
callback(error);
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
668
|
+
this[kPerformWithRetry]('deleteGroups', retryCallback => {
|
|
669
669
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: options.groups }, (error, coordinators) => {
|
|
670
670
|
if (error) {
|
|
671
|
-
|
|
671
|
+
// FindCoordinator already retried some times so no retry again
|
|
672
|
+
callback(new MultipleErrors('Deleting groups failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
672
673
|
return;
|
|
673
674
|
}
|
|
674
|
-
// Group the groups by coordinator
|
|
675
675
|
const coordinatorsMap = new Map();
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
676
|
+
// coordinators must be defined as error was undefined
|
|
677
|
+
for (const coordinator of coordinators) {
|
|
678
|
+
let coordinatorAggregate = coordinatorsMap.get(coordinator.nodeId);
|
|
679
|
+
if (!coordinatorAggregate) {
|
|
680
|
+
coordinatorAggregate = { host: coordinator.host, port: coordinator.port, groups: [] };
|
|
681
|
+
coordinatorsMap.set(coordinator.nodeId, coordinatorAggregate);
|
|
681
682
|
}
|
|
682
|
-
|
|
683
|
+
coordinatorAggregate.groups.push(coordinator.key);
|
|
683
684
|
}
|
|
684
|
-
runConcurrentCallbacks('Deleting groups failed.', coordinatorsMap, (
|
|
685
|
-
this[
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
685
|
+
runConcurrentCallbacks('Deleting groups failed.', coordinatorsMap.values(), (coordinator, concurrentCallback) => {
|
|
686
|
+
this[kPerformWithRetry]('deleteGroupsOnCoordinator', retryCallback => {
|
|
687
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
688
|
+
if (error) {
|
|
689
|
+
retryCallback(error);
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
691
692
|
this[kGetApi]('DeleteGroups', (error, api) => {
|
|
692
693
|
if (error) {
|
|
693
694
|
retryCallback(error);
|
|
694
695
|
return;
|
|
695
696
|
}
|
|
696
|
-
api(connection, groups, retryCallback);
|
|
697
|
+
api(connection, coordinator.groups, retryCallback);
|
|
697
698
|
});
|
|
698
|
-
}
|
|
699
|
-
});
|
|
700
|
-
},
|
|
699
|
+
});
|
|
700
|
+
}, concurrentCallback, 0);
|
|
701
|
+
}, retryCallback);
|
|
701
702
|
});
|
|
702
|
-
});
|
|
703
|
+
}, callback, 0);
|
|
703
704
|
}
|
|
704
705
|
#removeMembersFromConsumerGroup(options, callback) {
|
|
705
706
|
if (!options.members || options.members.length === 0) {
|
|
707
|
+
// Remove all members if none are specified
|
|
706
708
|
this.#describeGroups({ groups: [options.groupId] }, (error, groupsMap) => {
|
|
707
709
|
if (error) {
|
|
708
710
|
callback(new MultipleErrors('Removing members from consumer group failed.', [error]));
|
|
709
711
|
return;
|
|
710
712
|
}
|
|
713
|
+
// groupsMap must be defined as error was undefined
|
|
711
714
|
const group = groupsMap.get(options.groupId);
|
|
712
715
|
/* c8 ignore next 4 - Hard to test */
|
|
713
716
|
if (!group) {
|
|
@@ -724,61 +727,46 @@ export class Admin extends Base {
|
|
|
724
727
|
});
|
|
725
728
|
return;
|
|
726
729
|
}
|
|
727
|
-
this[
|
|
728
|
-
if (error) {
|
|
729
|
-
callback(error, undefined);
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
730
|
+
this[kPerformWithRetry]('removeMembersFromConsumerGroup', retryCallback => {
|
|
732
731
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
733
732
|
if (error) {
|
|
734
|
-
|
|
733
|
+
// FindCoordinator already retried some times so no retry again
|
|
734
|
+
callback(new MultipleErrors('Removing members from consumer group failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
735
735
|
return;
|
|
736
736
|
}
|
|
737
737
|
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
738
738
|
/* c8 ignore next 8 - Hard to test */
|
|
739
739
|
if (!coordinator) {
|
|
740
|
-
|
|
741
|
-
new Error(`No coordinator found for group ${options.groupId}`)
|
|
742
|
-
]));
|
|
740
|
+
retryCallback(new Error('Group coordinator not found'));
|
|
743
741
|
return;
|
|
744
742
|
}
|
|
745
|
-
|
|
746
|
-
/* c8 ignore next 8 - Hard to test */
|
|
747
|
-
if (!broker) {
|
|
748
|
-
callback(new MultipleErrors('Removing members from consumer group failed.', [
|
|
749
|
-
new Error(`Broker ${coordinator.nodeId} not found`)
|
|
750
|
-
]));
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
this[kGetConnection](broker, (error, connection) => {
|
|
743
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
754
744
|
if (error) {
|
|
755
|
-
|
|
745
|
+
retryCallback(error);
|
|
756
746
|
return;
|
|
757
747
|
}
|
|
758
|
-
this[
|
|
759
|
-
this[kGetApi]('LeaveGroup', (error, api) => {
|
|
760
|
-
if (error) {
|
|
761
|
-
retryCallback(error);
|
|
762
|
-
return;
|
|
763
|
-
}
|
|
764
|
-
/* c8 ignore next 5 - Hard to test */
|
|
765
|
-
const members = options.members.map(member => ({
|
|
766
|
-
memberId: typeof member === 'string' ? member : member.memberId,
|
|
767
|
-
groupInstanceId: null,
|
|
768
|
-
reason: typeof member === 'string' ? 'Not specified' : member.reason
|
|
769
|
-
}));
|
|
770
|
-
api(connection, options.groupId, members, retryCallback);
|
|
771
|
-
});
|
|
772
|
-
}, error => {
|
|
748
|
+
this[kGetApi]('LeaveGroup', (error, api) => {
|
|
773
749
|
if (error) {
|
|
774
|
-
|
|
750
|
+
retryCallback(error);
|
|
775
751
|
return;
|
|
776
752
|
}
|
|
777
|
-
|
|
778
|
-
|
|
753
|
+
/* c8 ignore next 5 - Hard to test */
|
|
754
|
+
const members = options.members.map(member => ({
|
|
755
|
+
memberId: typeof member === 'string' ? member : member.memberId,
|
|
756
|
+
groupInstanceId: null,
|
|
757
|
+
reason: typeof member === 'string' ? 'Not specified' : member.reason
|
|
758
|
+
}));
|
|
759
|
+
api(connection, options.groupId, members, retryCallback);
|
|
760
|
+
});
|
|
779
761
|
});
|
|
780
762
|
});
|
|
781
|
-
}
|
|
763
|
+
}, error => {
|
|
764
|
+
if (error) {
|
|
765
|
+
callback(new MultipleErrors('Removing members from consumer group failed.', [error]));
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
callback(null);
|
|
769
|
+
}, 0);
|
|
782
770
|
}
|
|
783
771
|
#findCoordinator(options, callback) {
|
|
784
772
|
this[kPerformWithRetry]('findCoordinator', retryCallback => {
|
|
@@ -797,7 +785,7 @@ export class Admin extends Base {
|
|
|
797
785
|
});
|
|
798
786
|
}, (error, response) => {
|
|
799
787
|
if (error) {
|
|
800
|
-
callback(error);
|
|
788
|
+
callback(new MultipleErrors('Finding coordinator failed.', [error]));
|
|
801
789
|
return;
|
|
802
790
|
}
|
|
803
791
|
callback(null, response.coordinators.map(coordinator => ({
|
|
@@ -855,19 +843,21 @@ export class Admin extends Base {
|
|
|
855
843
|
}, 0);
|
|
856
844
|
}
|
|
857
845
|
#describeLogDirs(options, callback) {
|
|
858
|
-
this[kMetadata]({ topics: [] }, (error, metadata) => {
|
|
846
|
+
this[kMetadata]({ topics: [], forceUpdate: true }, (error, metadata) => {
|
|
859
847
|
/* c8 ignore next 4 - Hard to test */
|
|
860
848
|
if (error) {
|
|
861
849
|
callback(error);
|
|
862
850
|
return;
|
|
863
851
|
}
|
|
864
|
-
runConcurrentCallbacks('Describing log dirs failed.',
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
852
|
+
runConcurrentCallbacks('Describing log dirs failed.',
|
|
853
|
+
// metadata must be defined as error was undefined
|
|
854
|
+
metadata.brokers, ([id, broker], concurrentCallback) => {
|
|
855
|
+
this[kPerformWithRetry]('describeLogDirs', retryCallback => {
|
|
856
|
+
this[kGetConnection](broker, (error, connection) => {
|
|
857
|
+
if (error) {
|
|
858
|
+
retryCallback(error);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
871
861
|
this[kGetApi]('DescribeLogDirs', (error, api) => {
|
|
872
862
|
if (error) {
|
|
873
863
|
retryCallback(error);
|
|
@@ -875,82 +865,84 @@ export class Admin extends Base {
|
|
|
875
865
|
}
|
|
876
866
|
api(connection, options.topics, retryCallback);
|
|
877
867
|
});
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
})
|
|
893
|
-
}
|
|
894
|
-
});
|
|
868
|
+
});
|
|
869
|
+
}, (error, response) => {
|
|
870
|
+
if (error) {
|
|
871
|
+
concurrentCallback(error);
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
concurrentCallback(null, {
|
|
875
|
+
broker: id,
|
|
876
|
+
throttleTimeMs: response.throttleTimeMs,
|
|
877
|
+
results: response.results.map(result => ({
|
|
878
|
+
logDir: result.logDir,
|
|
879
|
+
topics: result.topics,
|
|
880
|
+
totalBytes: result.totalBytes,
|
|
881
|
+
usableBytes: result.usableBytes
|
|
882
|
+
}))
|
|
883
|
+
});
|
|
884
|
+
}, 0);
|
|
895
885
|
}, callback);
|
|
896
886
|
});
|
|
897
887
|
}
|
|
898
888
|
#listConsumerGroupOffsets(options, callback) {
|
|
899
|
-
this[
|
|
900
|
-
if (error) {
|
|
901
|
-
callback(error);
|
|
902
|
-
return;
|
|
903
|
-
}
|
|
889
|
+
this[kPerformWithRetry]('listConsumerGroupOffsets', retryCallback => {
|
|
904
890
|
/* c8 ignore next - Hard to test */
|
|
905
891
|
const groupIds = options.groups.map(group => (typeof group === 'string' ? group : group.groupId));
|
|
906
892
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: groupIds }, (error, coordinators) => {
|
|
907
893
|
if (error) {
|
|
908
|
-
|
|
894
|
+
// FindCoordinator already retried some times so no retry again
|
|
895
|
+
callback(new MultipleErrors('Listing consumer group offsets failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
909
896
|
return;
|
|
910
897
|
}
|
|
911
898
|
const coordinatorsMap = new Map();
|
|
912
|
-
for (const
|
|
899
|
+
for (const coordinator of coordinators) {
|
|
913
900
|
const groupRequest = {
|
|
914
|
-
groupId,
|
|
901
|
+
groupId: coordinator.key,
|
|
915
902
|
memberId: null,
|
|
916
903
|
memberEpoch: -1
|
|
917
904
|
};
|
|
918
905
|
for (const group of options.groups) {
|
|
919
|
-
if (typeof group !== 'string' &&
|
|
906
|
+
if (typeof group !== 'string' &&
|
|
907
|
+
group.groupId === coordinator.key &&
|
|
908
|
+
!!group.topics &&
|
|
909
|
+
group.topics.length > 0) {
|
|
920
910
|
groupRequest.topics = group.topics;
|
|
921
911
|
break;
|
|
922
912
|
}
|
|
923
913
|
}
|
|
924
|
-
let
|
|
925
|
-
if (!
|
|
926
|
-
|
|
927
|
-
coordinatorsMap.set(
|
|
914
|
+
let offsetFetchRequestGroups = coordinatorsMap.get(coordinator.nodeId);
|
|
915
|
+
if (!offsetFetchRequestGroups) {
|
|
916
|
+
offsetFetchRequestGroups = { coordinator, groupRequests: [] };
|
|
917
|
+
coordinatorsMap.set(coordinator.nodeId, offsetFetchRequestGroups);
|
|
928
918
|
}
|
|
929
|
-
|
|
919
|
+
offsetFetchRequestGroups.groupRequests.push(groupRequest);
|
|
930
920
|
}
|
|
931
|
-
runConcurrentCallbacks('Listing consumer group offsets failed.', coordinatorsMap, (
|
|
932
|
-
this[
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
921
|
+
runConcurrentCallbacks('Listing consumer group offsets failed.', coordinatorsMap.values(), ({ coordinator, groupRequests }, concurrentCallback) => {
|
|
922
|
+
this[kPerformWithRetry]('offsetFetch', retryCallback => {
|
|
923
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
924
|
+
if (error) {
|
|
925
|
+
retryCallback(error);
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
938
928
|
this[kGetApi]('OffsetFetch', (error, api) => {
|
|
939
929
|
if (error) {
|
|
940
930
|
retryCallback(error);
|
|
941
931
|
return;
|
|
942
932
|
}
|
|
943
933
|
/* c8 ignore next - Hard to test */
|
|
944
|
-
api(connection,
|
|
934
|
+
api(connection, groupRequests, options.requireStable ?? false, retryCallback);
|
|
945
935
|
});
|
|
946
|
-
}
|
|
947
|
-
});
|
|
936
|
+
});
|
|
937
|
+
}, concurrentCallback, 0);
|
|
948
938
|
}, (error, responses) => {
|
|
949
939
|
if (error) {
|
|
950
|
-
|
|
940
|
+
retryCallback(error);
|
|
951
941
|
return;
|
|
952
942
|
}
|
|
953
|
-
|
|
943
|
+
retryCallback(null,
|
|
944
|
+
// responses must be defined as error was undefined
|
|
945
|
+
responses.flatMap(r => r.groups.map(group => ({
|
|
954
946
|
groupId: group.groupId,
|
|
955
947
|
topics: group.topics.map(topic => ({
|
|
956
948
|
name: topic.name,
|
|
@@ -964,125 +956,101 @@ export class Admin extends Base {
|
|
|
964
956
|
}))));
|
|
965
957
|
});
|
|
966
958
|
});
|
|
967
|
-
});
|
|
959
|
+
}, callback, 0);
|
|
968
960
|
}
|
|
969
961
|
#alterConsumerGroupOffsets(options, callback) {
|
|
970
|
-
this[
|
|
971
|
-
if (error) {
|
|
972
|
-
callback(error, undefined);
|
|
973
|
-
return;
|
|
974
|
-
}
|
|
962
|
+
this[kPerformWithRetry]('alterConsumerGroupOffsets', retryCallback => {
|
|
975
963
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
976
964
|
if (error) {
|
|
977
|
-
|
|
965
|
+
// FindCoordinator already retried some times so no retry again
|
|
966
|
+
callback(new MultipleErrors('Altering consumer group offsets failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
978
967
|
return;
|
|
979
968
|
}
|
|
980
969
|
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
981
970
|
/* c8 ignore next 9 - Hard to test */
|
|
982
971
|
if (!coordinator) {
|
|
983
|
-
|
|
984
|
-
new Error(`No coordinator found for group ${options.groupId}`)
|
|
985
|
-
]));
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
const broker = metadata.brokers.get(coordinator.nodeId);
|
|
989
|
-
/* c8 ignore next 9 - Hard to test */
|
|
990
|
-
if (!broker) {
|
|
991
|
-
callback(new MultipleErrors('Altering consumer group offsets failed.', [
|
|
992
|
-
new Error(`Broker ${coordinator.nodeId} not found`)
|
|
993
|
-
]));
|
|
972
|
+
retryCallback(new Error('Group coordinator not found'));
|
|
994
973
|
return;
|
|
995
974
|
}
|
|
996
|
-
this[kGetConnection](
|
|
975
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
997
976
|
if (error) {
|
|
998
|
-
|
|
977
|
+
retryCallback(error);
|
|
999
978
|
return;
|
|
1000
979
|
}
|
|
1001
|
-
this[
|
|
1002
|
-
this[kGetApi]('OffsetCommit', (error, api) => {
|
|
1003
|
-
if (error) {
|
|
1004
|
-
retryCallback(error);
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
const topics = [];
|
|
1008
|
-
for (const topic of options.topics) {
|
|
1009
|
-
const partitions = topic.partitionOffsets.map(p => ({
|
|
1010
|
-
partitionIndex: p.partition,
|
|
1011
|
-
committedOffset: p.offset,
|
|
1012
|
-
committedLeaderEpoch: -1,
|
|
1013
|
-
committedMetadata: null
|
|
1014
|
-
}));
|
|
1015
|
-
topics.push({ name: topic.name, partitions });
|
|
1016
|
-
}
|
|
1017
|
-
api(connection, options.groupId, -1, '', null, topics, retryCallback);
|
|
1018
|
-
});
|
|
1019
|
-
}, error => {
|
|
980
|
+
this[kGetApi]('OffsetCommit', (error, api) => {
|
|
1020
981
|
if (error) {
|
|
1021
|
-
|
|
982
|
+
retryCallback(error);
|
|
1022
983
|
return;
|
|
1023
984
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
985
|
+
const topics = [];
|
|
986
|
+
for (const topic of options.topics) {
|
|
987
|
+
const partitions = topic.partitionOffsets.map(p => ({
|
|
988
|
+
partitionIndex: p.partition,
|
|
989
|
+
committedOffset: p.offset,
|
|
990
|
+
committedLeaderEpoch: -1,
|
|
991
|
+
committedMetadata: null
|
|
992
|
+
}));
|
|
993
|
+
topics.push({ name: topic.name, partitions });
|
|
994
|
+
}
|
|
995
|
+
api(connection, options.groupId, -1, '', null, topics, retryCallback);
|
|
996
|
+
});
|
|
1026
997
|
});
|
|
1027
998
|
});
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
#deleteConsumerGroupOffsets(options, callback) {
|
|
1031
|
-
this[kMetadata]({ topics: [] }, (error, metadata) => {
|
|
999
|
+
}, error => {
|
|
1032
1000
|
if (error) {
|
|
1033
|
-
callback(error);
|
|
1001
|
+
callback(new MultipleErrors('Altering consumer group offsets failed.', [error]));
|
|
1034
1002
|
return;
|
|
1035
1003
|
}
|
|
1004
|
+
callback(null);
|
|
1005
|
+
}, 0);
|
|
1006
|
+
}
|
|
1007
|
+
#deleteConsumerGroupOffsets(options, callback) {
|
|
1008
|
+
this[kPerformWithRetry]('deleteConsumerGroupOffsets', retryCallback => {
|
|
1036
1009
|
this.#findCoordinator({ keyType: FindCoordinatorKeyTypes.GROUP, keys: [options.groupId] }, (error, coordinators) => {
|
|
1037
1010
|
if (error) {
|
|
1038
|
-
|
|
1011
|
+
// FindCoordinator already retried some times so no retry again
|
|
1012
|
+
callback(new MultipleErrors('Deleting consumer group offsets failed.', error instanceof MultipleErrors ? error.errors : [error]));
|
|
1039
1013
|
return;
|
|
1040
1014
|
}
|
|
1041
1015
|
const coordinator = coordinators.find(c => c.key === options.groupId);
|
|
1042
1016
|
/* c8 ignore next 9 - Hard to test */
|
|
1043
1017
|
if (!coordinator) {
|
|
1044
|
-
|
|
1045
|
-
new Error(`No coordinator found for group ${options.groupId}`)
|
|
1046
|
-
]));
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
const broker = metadata.brokers.get(coordinator.nodeId);
|
|
1050
|
-
/* c8 ignore next 9 - Hard to test */
|
|
1051
|
-
if (!broker) {
|
|
1052
|
-
callback(new MultipleErrors('Deleting consumer group offsets failed.', [
|
|
1053
|
-
new Error(`Broker ${coordinator.nodeId} not found`)
|
|
1054
|
-
]));
|
|
1018
|
+
retryCallback(new Error('Group coordinator not found'));
|
|
1055
1019
|
return;
|
|
1056
1020
|
}
|
|
1057
|
-
this[kGetConnection](
|
|
1021
|
+
this[kGetConnection](coordinator, (error, connection) => {
|
|
1058
1022
|
if (error) {
|
|
1059
|
-
|
|
1023
|
+
retryCallback(error);
|
|
1060
1024
|
return;
|
|
1061
1025
|
}
|
|
1062
|
-
this[
|
|
1063
|
-
|
|
1026
|
+
this[kGetApi]('OffsetDelete', (error, api) => {
|
|
1027
|
+
if (error) {
|
|
1028
|
+
retryCallback(error);
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
api(connection, options.groupId, options.topics.map(t => ({
|
|
1032
|
+
name: t.name,
|
|
1033
|
+
partitions: t.partitionIndexes.map(p => ({ partitionIndex: p }))
|
|
1034
|
+
})), (error, response) => {
|
|
1064
1035
|
if (error) {
|
|
1065
1036
|
retryCallback(error);
|
|
1066
1037
|
return;
|
|
1067
1038
|
}
|
|
1068
|
-
|
|
1069
|
-
name:
|
|
1070
|
-
|
|
1071
|
-
}))
|
|
1039
|
+
retryCallback(null, response.topics.map(topic => ({
|
|
1040
|
+
name: topic.name,
|
|
1041
|
+
partitionIndexes: topic.partitions.map(p => p.partitionIndex)
|
|
1042
|
+
})));
|
|
1072
1043
|
});
|
|
1073
|
-
}
|
|
1074
|
-
if (error) {
|
|
1075
|
-
callback(new MultipleErrors('Deleting consumer group offsets failed.', [error]));
|
|
1076
|
-
return;
|
|
1077
|
-
}
|
|
1078
|
-
callback(null, response.topics.map(topic => ({
|
|
1079
|
-
name: topic.name,
|
|
1080
|
-
partitionIndexes: topic.partitions.map(p => p.partitionIndex)
|
|
1081
|
-
})));
|
|
1082
|
-
}, 0);
|
|
1044
|
+
});
|
|
1083
1045
|
});
|
|
1084
1046
|
});
|
|
1085
|
-
})
|
|
1047
|
+
}, (error, results) => {
|
|
1048
|
+
if (error) {
|
|
1049
|
+
callback(new MultipleErrors('Deleting consumer group offsets failed.', [error]));
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
callback(null, results);
|
|
1053
|
+
}, 0);
|
|
1086
1054
|
}
|
|
1087
1055
|
#getConfigRequestsDistributedToBrokers(resources) {
|
|
1088
1056
|
const brokerConfigResourceMap = new Map();
|
|
@@ -1108,7 +1076,7 @@ export class Admin extends Base {
|
|
|
1108
1076
|
this[kGetBootstrapConnection](callback);
|
|
1109
1077
|
return;
|
|
1110
1078
|
}
|
|
1111
|
-
this[kMetadata]({ topics: [] }, (error, metadata) => {
|
|
1079
|
+
this[kMetadata]({ topics: [], forceUpdate: true }, (error, metadata) => {
|
|
1112
1080
|
/* c8 ignore next 4 - Hard to test */
|
|
1113
1081
|
if (error) {
|
|
1114
1082
|
callback(error);
|
|
@@ -1125,13 +1093,7 @@ export class Admin extends Base {
|
|
|
1125
1093
|
}
|
|
1126
1094
|
#describeConfigs(options, callback) {
|
|
1127
1095
|
runConcurrentCallbacks('Describing configs failed.', this.#getConfigRequestsDistributedToBrokers(options.resources), ([brokerId, resources], concurrentCallback) => {
|
|
1128
|
-
this.#describeConfigsOnBroker({ ...options, resources }, brokerId,
|
|
1129
|
-
if (error) {
|
|
1130
|
-
concurrentCallback(error);
|
|
1131
|
-
return;
|
|
1132
|
-
}
|
|
1133
|
-
concurrentCallback(null, response);
|
|
1134
|
-
});
|
|
1096
|
+
this.#describeConfigsOnBroker({ ...options, resources }, brokerId, concurrentCallback);
|
|
1135
1097
|
}, (error, results) => {
|
|
1136
1098
|
callback(error, results?.flat());
|
|
1137
1099
|
});
|
|
@@ -1307,154 +1269,166 @@ export class Admin extends Base {
|
|
|
1307
1269
|
}, 0);
|
|
1308
1270
|
}
|
|
1309
1271
|
#deleteRecords(options, callback) {
|
|
1310
|
-
this[
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
for (const topic of options.topics) {
|
|
1317
|
-
for (const partition of topic.partitions) {
|
|
1318
|
-
const { leader } = metadata.topics.get(topic.name).partitions[partition.partition];
|
|
1319
|
-
let leaderRequests = requestsByLeader.get(leader);
|
|
1320
|
-
if (!leaderRequests) {
|
|
1321
|
-
leaderRequests = new Map();
|
|
1322
|
-
requestsByLeader.set(leader, leaderRequests);
|
|
1323
|
-
}
|
|
1324
|
-
let topicRequest = leaderRequests.get(topic.name);
|
|
1325
|
-
if (!topicRequest) {
|
|
1326
|
-
topicRequest = { name: topic.name, partitions: [] };
|
|
1327
|
-
leaderRequests.set(topic.name, topicRequest);
|
|
1328
|
-
}
|
|
1329
|
-
topicRequest.partitions.push({
|
|
1330
|
-
partitionIndex: partition.partition,
|
|
1331
|
-
offset: partition.offset
|
|
1332
|
-
});
|
|
1272
|
+
this[kPerformWithRetry]('deleteRecords', retryCallback => {
|
|
1273
|
+
this[kMetadata]({ topics: options.topics.map(topic => topic.name), forceUpdate: true }, (error, metadata) => {
|
|
1274
|
+
if (error) {
|
|
1275
|
+
// Metadata request already retried some times so no retry again
|
|
1276
|
+
callback(error);
|
|
1277
|
+
return;
|
|
1333
1278
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1279
|
+
const requests = new Map();
|
|
1280
|
+
for (const topic of options.topics) {
|
|
1281
|
+
for (const partition of topic.partitions) {
|
|
1282
|
+
// metadata!.topics.get(topic.name) must be defined as the metadata request was successful
|
|
1283
|
+
const topicData = metadata.topics.get(topic.name);
|
|
1284
|
+
const targetPartitionData = topicData.partitions[partition.partition];
|
|
1285
|
+
/* c8 ignore next 4 - Hard to test */
|
|
1286
|
+
if (!targetPartitionData) {
|
|
1287
|
+
retryCallback(new UserError('Unknown partition.'));
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
const broker = metadata.brokers.get(targetPartitionData.leader);
|
|
1291
|
+
let leaderRequests = requests.get(broker);
|
|
1292
|
+
if (!leaderRequests) {
|
|
1293
|
+
leaderRequests = [];
|
|
1294
|
+
requests.set(broker, leaderRequests);
|
|
1295
|
+
}
|
|
1296
|
+
let topicRequest = leaderRequests.find(tr => tr.name === topic.name);
|
|
1297
|
+
if (!topicRequest) {
|
|
1298
|
+
topicRequest = { name: topic.name, partitions: [] };
|
|
1299
|
+
leaderRequests.push(topicRequest);
|
|
1300
|
+
}
|
|
1301
|
+
topicRequest.partitions.push({
|
|
1302
|
+
partitionIndex: partition.partition,
|
|
1303
|
+
offset: partition.offset
|
|
1304
|
+
});
|
|
1344
1305
|
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1306
|
+
}
|
|
1307
|
+
runConcurrentCallbacks('Deleting records failed.', requests, ([leader, requests], concurrentCallback) => {
|
|
1308
|
+
this[kPerformWithRetry]('deleteRecordsOnLeader', retryCallback => {
|
|
1309
|
+
this[kGetConnection](leader, (error, connection) => {
|
|
1347
1310
|
if (error) {
|
|
1348
1311
|
retryCallback(error);
|
|
1349
1312
|
return;
|
|
1350
1313
|
}
|
|
1351
|
-
|
|
1314
|
+
this[kGetApi]('DeleteRecords', (error, api) => {
|
|
1315
|
+
if (error) {
|
|
1316
|
+
retryCallback(error);
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
api(connection, requests, this[kOptions].timeout, retryCallback);
|
|
1320
|
+
});
|
|
1352
1321
|
});
|
|
1353
1322
|
}, concurrentCallback, 0);
|
|
1323
|
+
}, (error, responses) => {
|
|
1324
|
+
if (error) {
|
|
1325
|
+
// Do not retry failed deletion requests
|
|
1326
|
+
callback(error);
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
const deletedRecordsByTopic = new Map();
|
|
1330
|
+
for (const response of responses) {
|
|
1331
|
+
for (const topic of response.topics) {
|
|
1332
|
+
let topicDeletedRecords = deletedRecordsByTopic.get(topic.name);
|
|
1333
|
+
if (!topicDeletedRecords) {
|
|
1334
|
+
topicDeletedRecords = { name: topic.name, partitions: [] };
|
|
1335
|
+
deletedRecordsByTopic.set(topic.name, topicDeletedRecords);
|
|
1336
|
+
}
|
|
1337
|
+
for (const partition of topic.partitions) {
|
|
1338
|
+
topicDeletedRecords.partitions.push({
|
|
1339
|
+
partition: partition.partitionIndex,
|
|
1340
|
+
lowWatermark: partition.lowWatermark
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
retryCallback(null, Array.from(deletedRecordsByTopic.values()));
|
|
1354
1346
|
});
|
|
1355
|
-
}
|
|
1347
|
+
});
|
|
1348
|
+
}, callback, 0);
|
|
1349
|
+
}
|
|
1350
|
+
#listOffsets(options, callback) {
|
|
1351
|
+
this[kPerformWithRetry]('listOffsets', retryCallback => {
|
|
1352
|
+
this[kMetadata]({ topics: options.topics.map(topic => topic.name), forceUpdate: true }, (error, metadata) => {
|
|
1356
1353
|
if (error) {
|
|
1354
|
+
// Metadata request already retried some times so no retry again
|
|
1357
1355
|
callback(error);
|
|
1358
1356
|
return;
|
|
1359
1357
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1358
|
+
// metadata must be defined at this point
|
|
1359
|
+
const { topics, brokers } = metadata;
|
|
1360
|
+
const requests = new Map();
|
|
1361
|
+
for (const topic of options.topics) {
|
|
1362
|
+
for (const partition of topic.partitions) {
|
|
1363
|
+
// topics.get(topic.name) must be defined as the metadata request was successful
|
|
1364
|
+
const topicData = topics.get(topic.name);
|
|
1365
|
+
const targetPartitionData = topicData.partitions[partition.partitionIndex];
|
|
1366
|
+
/* c8 ignore next 4 - Hard to test */
|
|
1367
|
+
if (!targetPartitionData) {
|
|
1368
|
+
retryCallback(new UserError('Unknown partition.'));
|
|
1369
|
+
return;
|
|
1367
1370
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1371
|
+
const broker = brokers.get(targetPartitionData.leader);
|
|
1372
|
+
let leaderRequests = requests.get(broker);
|
|
1373
|
+
if (!leaderRequests) {
|
|
1374
|
+
leaderRequests = [];
|
|
1375
|
+
requests.set(broker, leaderRequests);
|
|
1373
1376
|
}
|
|
1377
|
+
let topicRequest = leaderRequests.find(t => t.name === topic.name);
|
|
1378
|
+
if (!topicRequest) {
|
|
1379
|
+
topicRequest = { name: topic.name, partitions: [] };
|
|
1380
|
+
leaderRequests.push(topicRequest);
|
|
1381
|
+
}
|
|
1382
|
+
topicRequest.partitions.push({
|
|
1383
|
+
partitionIndex: partition.partitionIndex,
|
|
1384
|
+
currentLeaderEpoch: targetPartitionData.leaderEpoch,
|
|
1385
|
+
/* c8 ignore next - Hard to test */
|
|
1386
|
+
timestamp: partition.timestamp ?? -1n
|
|
1387
|
+
});
|
|
1374
1388
|
}
|
|
1375
1389
|
}
|
|
1376
|
-
|
|
1377
|
-
});
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
#listOffsets(options, callback) {
|
|
1381
|
-
this[kMetadata]({ topics: options.topics.map(topic => topic.name) }, (error, metadata) => {
|
|
1382
|
-
if (error) {
|
|
1383
|
-
callback(error);
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1386
|
-
// metadata must be defined at this point
|
|
1387
|
-
const { topics, brokers } = metadata;
|
|
1388
|
-
const requests = new Map();
|
|
1389
|
-
for (const topic of options.topics) {
|
|
1390
|
-
for (const partition of topic.partitions) {
|
|
1391
|
-
// topics.get(topic.name) must be defined as the metadata request was successful
|
|
1392
|
-
const topicData = topics.get(topic.name);
|
|
1393
|
-
const targetPartitionData = topicData.partitions[partition.partitionIndex];
|
|
1394
|
-
/* c8 ignore next 4 - Hard to test */
|
|
1395
|
-
if (!targetPartitionData) {
|
|
1396
|
-
callback(new UserError(`Unknown partition ${partition.partitionIndex} for topic ${topic.name}.`));
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
let leaderRequests = requests.get(targetPartitionData.leader);
|
|
1400
|
-
if (!leaderRequests) {
|
|
1401
|
-
leaderRequests = [];
|
|
1402
|
-
requests.set(targetPartitionData.leader, leaderRequests);
|
|
1403
|
-
}
|
|
1404
|
-
let topicRequest = leaderRequests.find(t => t.name === topic.name);
|
|
1405
|
-
if (!topicRequest) {
|
|
1406
|
-
topicRequest = { name: topic.name, partitions: [] };
|
|
1407
|
-
leaderRequests.push(topicRequest);
|
|
1408
|
-
}
|
|
1409
|
-
topicRequest.partitions.push({
|
|
1410
|
-
partitionIndex: partition.partitionIndex,
|
|
1411
|
-
currentLeaderEpoch: targetPartitionData.leaderEpoch,
|
|
1412
|
-
/* c8 ignore next - Hard to test */
|
|
1413
|
-
timestamp: partition.timestamp ?? -1n
|
|
1414
|
-
});
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
runConcurrentCallbacks('Listing offsets failed.', requests, ([leader, requests], concurrentCallback) => {
|
|
1418
|
-
this[kGetConnection](brokers.get(leader), (error, connection) => {
|
|
1419
|
-
if (error) {
|
|
1420
|
-
concurrentCallback(error);
|
|
1421
|
-
return;
|
|
1422
|
-
}
|
|
1390
|
+
runConcurrentCallbacks('Listing offsets failed.', requests, ([leader, requests], concurrentCallback) => {
|
|
1423
1391
|
this[kPerformWithRetry]('listOffsets', retryCallback => {
|
|
1424
|
-
this[
|
|
1392
|
+
this[kGetConnection](leader, (error, connection) => {
|
|
1425
1393
|
if (error) {
|
|
1426
1394
|
retryCallback(error);
|
|
1427
1395
|
return;
|
|
1428
1396
|
}
|
|
1429
|
-
|
|
1397
|
+
this[kGetApi]('ListOffsets', (error, api) => {
|
|
1398
|
+
if (error) {
|
|
1399
|
+
retryCallback(error);
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
api(connection, -1, options.isolationLevel ?? FetchIsolationLevels.READ_UNCOMMITTED, requests, retryCallback);
|
|
1403
|
+
});
|
|
1430
1404
|
});
|
|
1431
1405
|
}, concurrentCallback, 0);
|
|
1432
|
-
})
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}
|
|
1406
|
+
}, (error, responses) => {
|
|
1407
|
+
if (error) {
|
|
1408
|
+
retryCallback(error);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
const ret = [];
|
|
1412
|
+
for (const response of responses) {
|
|
1413
|
+
for (const topic of response.topics) {
|
|
1414
|
+
let topicOffsets = ret.find(t => t.name === topic.name);
|
|
1415
|
+
if (!topicOffsets) {
|
|
1416
|
+
topicOffsets = { name: topic.name, partitions: [] };
|
|
1417
|
+
ret.push(topicOffsets);
|
|
1418
|
+
}
|
|
1419
|
+
for (const partition of topic.partitions) {
|
|
1420
|
+
topicOffsets.partitions.push({
|
|
1421
|
+
offset: partition.offset,
|
|
1422
|
+
timestamp: partition.timestamp,
|
|
1423
|
+
partitionIndex: partition.partitionIndex,
|
|
1424
|
+
leaderEpoch: partition.leaderEpoch
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1453
1427
|
}
|
|
1454
1428
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1429
|
+
retryCallback(null, ret);
|
|
1430
|
+
});
|
|
1457
1431
|
});
|
|
1458
|
-
});
|
|
1432
|
+
}, callback, 0);
|
|
1459
1433
|
}
|
|
1460
1434
|
}
|