Skip to content

Commit

Permalink
Fix on while joining channel peer display which is already part of ch…
Browse files Browse the repository at this point in the history
…annel (#638)

Signed-off-by: Chandra Kant Paliwal <paliwal.ck+ibm@gmail.com>
  • Loading branch information
ckpaliwal authored Feb 23, 2024
1 parent 2b4473e commit b85c839
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 18 deletions.
157 changes: 147 additions & 10 deletions packages/apollo/src/components/JoinChannelModal/JoinChannelModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EventsRestApi } from '../../rest/EventsRestApi';
import { MspRestApi } from '../../rest/MspRestApi';
import { OrdererRestApi } from '../../rest/OrdererRestApi';
import { PeerRestApi } from '../../rest/PeerRestApi';
import SignatureRestApi from '../../rest/SignatureRestApi';
import Helper from '../../utils/helper';
import NodeStatus from '../../utils/status';
import ConfigOverride from '../ConfigOverride/ConfigOverride';
Expand All @@ -41,6 +42,12 @@ const Log = new Logger(SCOPE);

class JoinChannelModal extends React.Component {
async componentDidMount() {
let channelList = this.props.channelList;
if (!channelList) {
const { channels } = await ChannelApi.getAllChannels();
this.populatePendingChannels(channels);
channelList = channels;
}
const orderers = await OrdererRestApi.getOrderers(true);
let channel = this.props.isPending ? this.props.pendingChannelName : this.props.isAddingNode ? this.props.existingChannel : '';
this.props.updateState(SCOPE, {
Expand All @@ -57,6 +64,7 @@ class JoinChannelModal extends React.Component {
addressOverrides: [],
channel_warning_20_details: [],
channel_warning_20: false,
channelList,
});
let orderer = this.props.orderer;
if (this.props.isAddingNode && this.props.existingOrderer) {
Expand All @@ -83,6 +91,131 @@ class JoinChannelModal extends React.Component {
}
}


async getCreateChannelRequests() {
let requests = [];
if (this.props.signature_requests && this.props.signature_requests.length) {
this.props.signature_requests.forEach(req => {
if (this.isVisibleCreateRequest(req)) {
requests.push(req);
}
});
} else {
requests = await SignatureRestApi.getCreateChannelRequests();
}
return requests;
};

populatePendingChannels = joinedChannels => {
OrdererRestApi.getOrderers(false).then(async orderers => {
if (!this.mounted) {
return;
}

// Build list that includes all raft nodes from all the console ordering services
let all_nodes = [];
orderers.forEach(orderer => {
if (_.has(orderer, 'raft')) {
orderer.raft.forEach(x => all_nodes.push(x));
} else {
all_nodes.push(orderer);
}
});

// Get pending channels from notifications instead of local storage
const pendingChannels = [];
let signature_requests = await this.getCreateChannelRequests();
signature_requests.forEach(notification => {
let notification_orderers = [];
if (_.has(notification, 'consenters')) {
notification.consenters.forEach(url => {
let orderer_details = all_nodes.find(x => _.toLower(x.backend_addr) === _.toLower(url));
if (orderer_details) {
notification_orderers.push(orderer_details);
} else {
notification_orderers.push({ backend_addr: url, name: url });
}
});
} else {
// If there were pending tiles before migrating to 2.1.3, handle them the old way so that we dont loose the tile after migration
notification.orderers.forEach(url => {
let orderer_details = all_nodes.find(x => {
const url1 = x.url2use.substring(x.url2use.indexOf('/grpcwp/') + 8); // Proxy ports have changed, so compare only url after /grpcwp/
const url2 = url.indexOf('/grpcwp/') > 0 ? url.substring(url.indexOf('/grpcwp/') + 8) : url;
return _.toLower(decodeURIComponent(url1)) === _.toLower(decodeURIComponent(url2));
});
if (orderer_details) {
notification_orderers.push(orderer_details);
} else {
notification_orderers.push({ backend_addr: url, name: url });
}
});
}
let matchingJoinedChannel =
joinedChannels && joinedChannels.length
? joinedChannels.find(channel => {
let allChannelOrderers = [];
if (channel.orderers) {
channel.orderers.forEach(orderer => {
if (_.has(orderer, 'raft')) {
orderer.raft.forEach(y => allChannelOrderers.push(y));
} else {
allChannelOrderers.push(orderer);
}
});
}
let joinedChannelOrderers = allChannelOrderers.map(orderer => (orderer.backend_addr ? orderer.backend_addr : orderer.name));
let pendingChannelOrderers = notification_orderers
? notification_orderers.map(orderer => (orderer ? (orderer.backend_addr ? orderer.backend_addr : orderer.name) : ''))
: [];
let match = channel.name === notification.channel && _.intersection(pendingChannelOrderers, joinedChannelOrderers).length > 0;
return match;
})
: null;
if (!matchingJoinedChannel) {
pendingChannels.push({
id: notification.channel,
name: notification.channel,
orderers: notification_orderers,
pending: true,
});
}
});

let allChannels = _.size(joinedChannels) > 0 ? joinedChannels.concat(pendingChannels) : pendingChannels;
// Filter out the pending channels whose orderers are not imported in this console
let filteredChannels = [];
if (_.size(all_nodes) > 0) {
const all_nodes_grpcurls = all_nodes.map(x => x.grpcwp_url); // To support older notifications that dont have consenters data
const all_nodes_backendaddr = all_nodes.map(x => x.backend_addr);
const all_nodes_url2use = all_nodes.map(x => x.url2use);
const consoleOrdererAddresses = all_nodes_backendaddr.concat(all_nodes_grpcurls).concat(all_nodes_url2use);

filteredChannels = allChannels.filter(channel => {
let channelOrdererAddresses = channel.orderers.map(x => x.backend_addr);
return channel.pending ? _.intersection(consoleOrdererAddresses, channelOrdererAddresses).length > 0 : channel;
});
} else {
filteredChannels = allChannels.filter(channel => {
return channel.pending ? false : channel;
});
}
// Pending tile should show only one associated orderer(which includes all the raft nodes)
pendingChannels.forEach(pc => {
let pc_cluster_ids = pc.orderers.map(x => x.cluster_id);
orderers.forEach(orderer => {
if (pc_cluster_ids.includes(orderer.cluster_id)) {
pc.orderers = [orderer];
}
});
});

Log.debug('All channels:', allChannels);
Log.debug('Filtered channels:', filteredChannels);
return filteredChannels;
});
};

async calculateCapabilityWarning(channel_config, orderer, selectedPeers, channel) {
let all_warning_20 = false;
let all_warning_20_details = [];
Expand Down Expand Up @@ -504,8 +637,8 @@ class JoinChannelModal extends React.Component {
this.checkPeerMappings(change.selectedPeers);
};

onChannelChange = (change, valid) => {
this.props.updateState(SCOPE, { disableSubmit: !valid });
onChannelChange = async (change, valid) => {
this.props.updateState(SCOPE, { disableSubmit: !valid, channel: change.selectedChannel.id, existingMembers: change.selectedChannel.peers });
};

toggleAnchorPeer = () => {
Expand Down Expand Up @@ -721,6 +854,7 @@ class JoinChannelModal extends React.Component {
);
}


renderSelectChannel(translate) {
if (this.props.hideChannelStep || this.props.isPending) {
return;
Expand All @@ -732,19 +866,19 @@ class JoinChannelModal extends React.Component {
headerLink={translate('_JOIN_CHANNEL_LINK', { DOC_PREFIX: this.props.docPrefix })}
headerLinkText={translate('find_out_more')}
title={translate('select_channel')}
disableSubmit={this.props.disableSubmit}
// disableSubmit={this.props.disableSubmit}
disableSubmit={!this.props.channel}
onNext={() => this.filterPeers()}
>
<Form
scope={SCOPE}
id={SCOPE + '-channel'}
fields={[
{
name: 'channel',
specialRules: Helper.SPECIAL_RULES_CHANNEL_NAME,
required: true,
},
]}
fields={[{
name: 'selectedChannel',
type: 'dropdown',
options: this.props.channelList,
default: 'select_channel_title'
}]}
onChange={this.onChannelChange}
/>
</WizardStep>
Expand Down Expand Up @@ -810,6 +944,8 @@ const dataProps = {
addressOverrides: PropTypes.array,
channel_warning_20: PropTypes.bool,
channel_warning_20_details: PropTypes.array,
existingMembers: PropTypes.any,
channelList: PropTypes.array
};

JoinChannelModal.propTypes = {
Expand All @@ -823,6 +959,7 @@ JoinChannelModal.propTypes = {
export default connect(
state => {
let newProps = Helper.mapStateToProps(state[SCOPE], dataProps);
newProps['channelList'] = newProps.channelList ? newProps.channelList : state['channels'] ? state['channels']['filteredChannels'] : null;
newProps['CRN'] = state['settings'] ? state['settings']['CRN'] : null;
newProps['userInfo'] = state['userInfo'] ? state['userInfo']['loggedInAs'] : null;
newProps['configtxlator_url'] = state['settings']['configtxlator_url'];
Expand Down
4 changes: 2 additions & 2 deletions packages/apollo/src/rest/EventsRestApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class EventsRestApi {
}).join(', ');
EventsRestApi.recordActivity({
status: status === 'error' ? 'error' : 'success',
log: `${peers.length > 1 ? 'peers' : 'peer'} ${peer_names} ${peers.length > 1 ? 'have' : 'has'} ${status === 'error' ? 'failed to ' : ''} joined the channel "${channel_id}"`,
log: `${peers.length > 1 ? 'peers' : 'peer'} ${peer_names} ${peers.length > 1 ? 'have' : 'has'} ${status === 'error' ? 'failed to ' : ''}joined the channel "${channel_id}"`,
code: status === 'error' ? 403 : 200
});
} catch (e) {
Expand All @@ -86,7 +86,7 @@ class EventsRestApi {
}).join(', ');
EventsRestApi.recordActivity({
status: status === 'error' ? 'error' : 'success',
log: `${peers.length > 1 ? 'peers' : 'peer'} ${peer_names} ${peers.length > 1 ? 'have' : 'has'} ${status === 'error' ? 'failed to ' : ''} disconnect from the channel "${channel_id}"`,
log: `${peers.length > 1 ? 'peers' : 'peer'} ${peer_names} ${peers.length > 1 ? 'have' : 'has'} ${status === 'error' ? 'failed to ' : ''}disconnect from the channel "${channel_id}"`,
code: status === 'error' ? 403 : 200
});
} catch (e) {
Expand Down
6 changes: 0 additions & 6 deletions packages/apollo/src/utils/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,10 @@ const NodeStatus = {
}
}

console.log('ibp99 - getStatusFromPhase', status);
return status;
},

checkResources(node) {
console.log('ibp99 - checkResources', node.id);
return new Promise((resolve, reject) => {
NodeRestApi.api_getCurrentNodeDeployer(node)
.then(resp => {
Expand All @@ -85,10 +83,8 @@ const NodeStatus = {
});
} else {
if ((node.type === 'fabric-orderer' || node.type === 'orderer') && node.consenter_proposal_fin === false) {
console.log('ibp99 - getting comp status from deployer', node.id);
NodeRestApi.getNodeDetailsFromDeployer(node.id)
.then(() => {
console.log('ibp99 - deployer says the component is running', node.id);
resolve({
id: node.id,
status: 'running',
Expand Down Expand Up @@ -266,7 +262,6 @@ const NodeStatus = {
// all good, so return status
}
if (status) {
console.log('ibp99 - getStatusInternal 1', id, status);
this.updateStatus(id, status, scope, prop, callback);
complete[id] = true;
}
Expand All @@ -284,7 +279,6 @@ const NodeStatus = {
if (this.in_progress[id]) {
results_list.forEach(result => {
if (result && result.id) {
console.log('ibp99 - getStatusInternal 2', result.id, result.status);
this.updateStatus(result.id, result.status, scope, prop, callback);
switch (result.status) {
case 'initialized':
Expand Down

0 comments on commit b85c839

Please sign in to comment.