diff --git a/docs/reference/15_members.adoc b/docs/reference/15_members.adoc index decb6135..4bc2bb91 100644 --- a/docs/reference/15_members.adoc +++ b/docs/reference/15_members.adoc @@ -107,9 +107,9 @@ Output: ---- NODE ID ADDRESS PORT PROCESS MEMBER ROLE PKT SENT PKT REC RESENT EFFICIENCY SEND Q DATA SENT DATA REC WEAKEST 1 /127.0.0.1 50724 81363 storage-1 CoherenceServer 531 586 2 100.00% 0 8 MB 9 MB 4 - 2 /127.0.0.1 50725 81364 storage-2 CoherenceServer 181 152 0 100.00% 0 8 MB 8 MB -1 - 3 /127.0.0.1 50726 81362 storage-0 CoherenceServer 182 148 0 100.00% 0 7 MB 10 MB -1 - 4 /127.0.0.1 50968 81733 com.tangosol.net.CacheFactory CoherenceConsole 64 58 0 100.00% 0 3 MB 0 MB -1 + 2 /127.0.0.1 50725 81364 storage-2 CoherenceServer 181 152 0 100.00% 0 8 MB 8 MB - + 3 /127.0.0.1 50726 81362 storage-0 CoherenceServer 182 148 0 100.00% 0 7 MB 10 MB - + 4 /127.0.0.1 50968 81733 com.tangosol.net.CacheFactory CoherenceConsole 64 58 0 100.00% 0 3 MB 0 MB - ---- [#get-p2p-stats] diff --git a/docs/reference/20_services.adoc b/docs/reference/20_services.adoc index 89fed12f..22e0cd0d 100644 --- a/docs/reference/20_services.adoc +++ b/docs/reference/20_services.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2021, 2023 Oracle and/or its affiliates. + Copyright (c) 2021, 2024 Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. @@ -238,11 +238,11 @@ Output: [source,bash] ---- SERVICE NAME TYPE MEMBERS STATUS HA STORAGE SENIOR PARTITIONS -Proxy Proxy 2 n/a -1 1 -1 +Proxy Proxy 2 n/a 0 1 - PartitionedTopic DistributedCache 2 NODE-SAFE 2 2 257 PartitionedCache2 DistributedCache 2 NODE-SAFE 2 2 257 PartitionedCache DistributedCache 2 NODE-SAFE 2 1 257 -ManagementHttpProxy Proxy 1 n/a -1 1 -1 +ManagementHttpProxy Proxy 1 n/a 0 1 - ---- [source,bash] diff --git a/pkg/cmd/cache.go b/pkg/cmd/cache.go index 35ef46c8..c0bf43d0 100644 --- a/pkg/cmd/cache.go +++ b/pkg/cmd/cache.go @@ -37,8 +37,8 @@ var ( ) const ( - provideCacheMessage = "you must provide a cache name" - provideViewCacheMessage = "you must provide a view cache name" + provideCacheMessage = "you must provide a single cache name" + provideViewCacheMessage = "you must provide a single view cache name" back = "back" all = "all" partitionDisplayType = "partition" @@ -800,7 +800,7 @@ batchFactor, refreshFactor or requeueThreshold.`, ValidArgsFunction: completionCaches, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a cache name") + displayErrorAndExit(cmd, provideCacheMessage) } return nil }, diff --git a/pkg/cmd/cluster.go b/pkg/cmd/cluster.go index a11a2ba4..48614c5f 100644 --- a/pkg/cmd/cluster.go +++ b/pkg/cmd/cluster.go @@ -34,9 +34,9 @@ var ( ) const ( - clusterMessage = "A cluster connection already exists with the name %s for %s\n" - ignoreErrorsMessage = "ignore errors from NS lookup" - youMustProviderClusterMessage = "you must provide a cluster name" + clusterMessage = "A cluster connection already exists with the name %s for %s\n" + ignoreErrorsMessage = "ignore errors from NS lookup" + youMustProviderConnectionMessage = "you must provide a single connection name" ) // addClusterCmd represents the add cluster command @@ -49,7 +49,7 @@ You can also specify host:port (for http connections) and the url will be automa populated constructed.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a connection name") + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -62,7 +62,7 @@ populated constructed.`, } if connectionURL == "" { - return errors.New("you must supply a connection url") + return errors.New("you must provide a connection url") } if err = addCluster(cmd, connection, connectionURL, "manual", ""); err != nil { @@ -81,7 +81,7 @@ var removeClusterCmd = &cobra.Command{ ValidArgsFunction: completionAllClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a connection name") + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -203,7 +203,7 @@ addition information as well as '-v' to displayed additional information.`, ValidArgsFunction: completionAllClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a cluster connection") + displayErrorAndExit(cmd, "you must provide a single cluster connection") } return nil }, @@ -774,7 +774,7 @@ commercial 14.1.1.2206.1 and above. Default version is currently CE ` + defaultC NOTE: This is an experimental feature and my be altered or removed in the future.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -1141,7 +1141,7 @@ var startClusterCmd = &cobra.Command{ ValidArgsFunction: completionAllManualClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -1161,7 +1161,7 @@ var scaleClusterCmd = &cobra.Command{ ValidArgsFunction: completionAllManualClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -1178,7 +1178,7 @@ var stopClusterCmd = &cobra.Command{ ValidArgsFunction: completionAllManualClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -1195,7 +1195,7 @@ var restartClusterCmd = &cobra.Command{ ValidArgsFunction: completionAllManualClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, diff --git a/pkg/cmd/context.go b/pkg/cmd/context.go index 0d5d60c5..a297cbdf 100644 --- a/pkg/cmd/context.go +++ b/pkg/cmd/context.go @@ -27,7 +27,7 @@ var setContextCmd = &cobra.Command{ ValidArgsFunction: completionAllClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a connection name") + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, diff --git a/pkg/cmd/environment.go b/pkg/cmd/environment.go index 30d46b2f..02fdae3b 100644 --- a/pkg/cmd/environment.go +++ b/pkg/cmd/environment.go @@ -23,7 +23,7 @@ This includes details of the JVM as well as system properties.`, ValidArgsFunction: completionNodeID, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a node id") + displayErrorAndExit(cmd, "you must provide a single node id") } return nil }, diff --git a/pkg/cmd/executor.go b/pkg/cmd/executor.go index 0a254a18..cde3a020 100644 --- a/pkg/cmd/executor.go +++ b/pkg/cmd/executor.go @@ -27,7 +27,7 @@ var ( ) const ( - provideExecutorName = "you must provide an executor name" + provideExecutorName = "you must provide a single executor name" cannotFindExecutors = "unable to find any executors in this cluster" stringTrue = "true" stringFalse = "false" diff --git a/pkg/cmd/federation.go b/pkg/cmd/federation.go index 85823ded..896dfd0f 100644 --- a/pkg/cmd/federation.go +++ b/pkg/cmd/federation.go @@ -21,12 +21,12 @@ import ( ) const ( - destinations = "destinations" - origins = "origins" + destinations = "outgoing" + origins = "incoming" outgoing = "outgoing" incoming = "incoming" participantMessage = "participant to apply to" - supplyService = "you must provide a service name" + supplyService = "you must provide a single federated service name" federationUse = "federation service-name" replicateAll = "replicateAll" ) @@ -42,10 +42,10 @@ var ( // getFederationCmd represents the get federation command. var getFederationCmd = &cobra.Command{ - Use: "federation {destinations|origins|all}", + Use: "federation {outgoing|incoming|all}", Short: "display federation details for a cluster", Long: `The 'get federation' command displays the federation details for a cluster. -You must specify either destinations, origins or all to show both. You +You must specify either outgoing, incoming or all to show both. You can also specify '-o wide' to display addition information.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { @@ -109,7 +109,7 @@ can also specify '-o wide' to display addition information.`, jsonDataDest, _ := json.Marshal(finalSummariesDestinations) jsonDataOrigins, _ := json.Marshal(finalSummariesOrigins) finalData, err := utils.CombineByteArraysForJSON([][]byte{jsonDataDest, jsonDataOrigins}, - []string{"destinations", "origins"}) + []string{outgoing, incoming}) if err != nil { return err } diff --git a/pkg/cmd/formatting.go b/pkg/cmd/formatting.go index 81a4eee6..3c174d32 100644 --- a/pkg/cmd/formatting.go +++ b/pkg/cmd/formatting.go @@ -236,7 +236,7 @@ func FormatFederationDetails(federationDetails []config.FederationDescription, t var nodeID, _ = strconv.Atoi(value.NodeID) table.AddRow(formatSmallInteger(int32(nodeID))) - if target == "destinations" { + if target == destinations { bytes = value.TotalBytesSent messages = value.TotalMsgSent records = value.TotalRecordsSent @@ -288,7 +288,7 @@ func FormatFederationSummary(federationSummaries []config.FederationSummary, tar fedCount = len(federationSummaries) finalAlignment []string suffix = "SENT" - participantCol = "DESTINATION" + participantCol = "OUTGOING" memberCol = MembersColumn formattingFunction = getFormattingFunction() table FormattedTable @@ -301,7 +301,7 @@ func FormatFederationSummary(federationSummaries []config.FederationSummary, tar // setup columns and alignments if target == origins { suffix = "REC" - participantCol = "ORIGIN" + participantCol = "INCOMING" memberCol = "MEMBERS RECEIVING" } @@ -359,7 +359,7 @@ func FormatFederationSummary(federationSummaries []config.FederationSummary, tar ) for _, value := range federationSummaries { - if target == "destinations" { + if target == destinations { bytes = value.TotalBytesSent.Sum messages = value.TotalMsgSent.Sum records = value.TotalRecordsSent.Sum @@ -956,8 +956,8 @@ func FormatCacheDetailsSizeAndAccess(cacheDetails []config.CacheDetail) string { if OutputFormat == constants.WIDE { table.AddColumnsToRow(formatLargeInteger(totalHits), formatLargeInteger(value.CacheMisses), formatPercent(hitProb), - formatLargeInteger(value.StoreReads), formatLargeInteger(value.StoreWrites), - formatLargeInteger(value.StoreFailures)) + formatLargeIntegerOrDash(value.StoreReads), formatLargeIntegerOrDash(value.StoreWrites), + formatLargeIntegerOrDash(value.StoreFailures)) } } @@ -1193,7 +1193,7 @@ func FormatClusterConnections(clusters []ClusterConnection) string { return "" } - table := newFormattedTable().WithHeader("CONNECTION", "TYPE", "URL", "VERSION", "CLUSTER NAME", "TYPE", "CTX", "LOCAL"). + table := newFormattedTable().WithHeader("CONNECTION", "TYPE", "URL", "VERSION", "CLUSTER NAME", "TYPE", "CTX", "CREATED"). WithSortingColumn("CONNECTION") for _, value := range clusters { @@ -1521,7 +1521,7 @@ func FormatNetworkStatistics(members []config.Member) string { table.AddColumnsToRow(formatLargeInteger(value.PacketsSent), formatLargeInteger(value.PacketsReceived), formatLargeInteger(value.PacketsResent), formatPercent(value.PacketDeliveryEfficiency), formatLargeInteger(value.SendQueueSize), formattingFunction(value.TransportSentBytes), - formattingFunction(value.TransportReceivedBytes), formatSmallInteger(value.WeakestChannel)) + formattingFunction(value.TransportReceivedBytes), formatSmallIntegerOrDash(value.WeakestChannel)) } return table.String() @@ -1685,8 +1685,8 @@ func FormatServices(services []config.ServiceSummary) string { table := newFormattedTable().WithHeader(ServiceNameColumn, "TYPE", MembersColumn, "STATUS HA", "STORAGE", "SENIOR", partitions, "STATUS").WithSortingColumn(ServiceNameColumn) if OutputFormat == constants.WIDE { - table.WithAlignment(L, L, R, L, R, R, R, L, R, R, R, L) - table.AddHeaderColumns(endangered, "VULNERABLE", "UNBALANCED", "SUSPENDED") + table.WithAlignment(L, L, R, L, R, R, R, L, R, R, R, R, L) + table.AddHeaderColumns(endangered, "VULNERABLE", "UNBALANCED", "PENDING REQ", "SUSPENDED") table.AddFormattingFunction(8, endangeredPartitionsFormatter) table.AddFormattingFunction(9, vulnerablePartitionsFormatter) table.AddFormattingFunction(10, vulnerablePartitionsFormatter) @@ -1696,7 +1696,7 @@ func FormatServices(services []config.ServiceSummary) string { } table.AddFormattingFunction(3, statusHAFormatter) - table.AddFormattingFunction(7, statusHAFormatter) + table.AddFormattingFunction(8, statusHAFormatter) for _, value := range services { var ( @@ -1715,6 +1715,10 @@ func FormatServices(services []config.ServiceSummary) string { status = fmt.Sprintf("%d partitions are unbalanced", value.PartitionsUnbalanced) } + if value.StorageEnabledCount == -1 { + value.StorageEnabledCount = 0 + } + if value.QuorumStatus == "Suspended" { suspended = "yes" } else { @@ -1725,12 +1729,13 @@ func FormatServices(services []config.ServiceSummary) string { table.AddRow(value.ServiceName, value.ServiceType, formatSmallInteger(value.MemberCount), value.StatusHA, formatSmallInteger(value.StorageEnabledCount), formatSmallInteger(value.SeniorMemberID), - formatSmallInteger(value.PartitionsAll), status) + formatSmallIntegerOrDash(value.PartitionsAll), status) if OutputFormat == constants.WIDE { - table.AddColumnsToRow(formatSmallInteger(value.PartitionsEndangered), - formatSmallInteger(value.PartitionsVulnerable), - formatSmallInteger(value.PartitionsUnbalanced), suspended) + table.AddColumnsToRow(formatSmallIntegerOrDash(value.PartitionsEndangered), + formatSmallIntegerOrDash(value.PartitionsVulnerable), + formatSmallIntegerOrDash(value.PartitionsUnbalanced), + formatSmallInteger(value.RequestPendingCount), suspended) } } @@ -2098,6 +2103,22 @@ func formatSmallInteger(value int32) string { return printer.Sprintf("%d", value) } +// formatSmallIntegerOrDash formats a small integer but if the value is -1 returns "n/a" +func formatSmallIntegerOrDash(value int32) string { + if value == -1 { + return "-" + } + return formatSmallInteger(value) +} + +// formatLargeIntegerOrDash formats a large integer but if the value is -1 returns "n/a" +func formatLargeIntegerOrDash(value int64) string { + if value == -1 { + return "-" + } + return formatLargeInteger(value) +} + // formatPort formats a small integer with a max length. func formatPort(value int32) string { return fmt.Sprintf("%d", value) diff --git a/pkg/cmd/http_server.go b/pkg/cmd/http_server.go index 5466bdd2..c9897591 100644 --- a/pkg/cmd/http_server.go +++ b/pkg/cmd/http_server.go @@ -35,7 +35,7 @@ var getHTTPProxiesCmd = &cobra.Command{ return err } - details, err := returnGetProxiesDetails(cmd, httpString, dataFetcher, connection) + details, err := returnGetProxiesDetails(cmd, httpString, dataFetcher, connection, "") if err != nil { return err } @@ -55,7 +55,7 @@ var describeHTTPProxyCmd = &cobra.Command{ ValidArgsFunction: completionHTTPServers, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a service name") + displayErrorAndExit(cmd, provideService) } return nil }, @@ -99,7 +99,7 @@ var describeHTTPProxyCmd = &cobra.Command{ return err } - err = displayProxyDetails(cmd, dataFetcher, connection, httpString, serviceResult, proxyResults) + err = displayProxyDetails(cmd, dataFetcher, connection, httpString, serviceResult, proxyResults, serviceName) if err != nil { return err } diff --git a/pkg/cmd/http_session.go b/pkg/cmd/http_session.go index 14021cdc..2caf7035 100644 --- a/pkg/cmd/http_session.go +++ b/pkg/cmd/http_session.go @@ -137,7 +137,7 @@ var describeHTTPSessionCmd = &cobra.Command{ ValidArgsFunction: completionHTTPSessions, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide an application id") + displayErrorAndExit(cmd, "you must provide a single application id") } return nil }, diff --git a/pkg/cmd/jfr.go b/pkg/cmd/jfr.go index 925af6a7..1ea50ca5 100644 --- a/pkg/cmd/jfr.go +++ b/pkg/cmd/jfr.go @@ -28,7 +28,7 @@ var ( const ( jfrNameUse = "jfr name" - supplyJFR = "you must provide a JFR name" + provideJFR = "you must provide a single JFR name" ) // getJfrsCmd represents the get jfrs command. @@ -60,7 +60,7 @@ var describeJfrCmd = &cobra.Command{ Long: `The 'describe jfr' command shows information related to a Java Flight Recording (JFR).`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, supplyJFR) + displayErrorAndExit(cmd, provideJFR) } return nil }, @@ -90,7 +90,7 @@ be run for all members. The default duration is 60 seconds and you can specify a of 0 to make the recording continuous.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, supplyJFR) + displayErrorAndExit(cmd, provideJFR) } return nil }, @@ -179,7 +179,7 @@ var stopJfrCmd = &cobra.Command{ You can specify either a node or leave the node blank to stop for all nodes.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, supplyJFR) + displayErrorAndExit(cmd, provideJFR) } return nil }, @@ -207,7 +207,7 @@ var dumpJfrCmd = &cobra.Command{ A JFR command mut be in progress for this to succeed.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, supplyJFR) + displayErrorAndExit(cmd, provideJFR) } return nil }, diff --git a/pkg/cmd/machine.go b/pkg/cmd/machine.go index d00a4c6e..2aaf18d2 100644 --- a/pkg/cmd/machine.go +++ b/pkg/cmd/machine.go @@ -164,7 +164,7 @@ var describeMachineCmd = &cobra.Command{ ValidArgsFunction: completionMachines, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a machine name") + displayErrorAndExit(cmd, "you must provide a single machine name") } return nil }, diff --git a/pkg/cmd/monitor_cluster.go b/pkg/cmd/monitor_cluster.go index bd12bf29..e411b7c9 100644 --- a/pkg/cmd/monitor_cluster.go +++ b/pkg/cmd/monitor_cluster.go @@ -24,7 +24,7 @@ import ( const ( defaultLayoutName = "default" pressAdditional = "(press key in [] or mouse to toggle expand, ? = help)" - pressAdditionalReset = "(press key in [] or mouse to exit expand)" + pressAdditionalReset = "(press key in [] or mouse/ESC to exit expand)" noContent = " No Content" errorContent = "Unable to retrieve data" unableToFindPanel = "unable to find panel [%v], use --help or --show-panels to see all options" @@ -137,7 +137,7 @@ Use --show-panels to show all available panels.`, ValidArgsFunction: completionAllClusters, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 && !showAllPanels { - displayErrorAndExit(cmd, youMustProviderClusterMessage) + displayErrorAndExit(cmd, youMustProviderConnectionMessage) } return nil }, @@ -282,7 +282,7 @@ Use --show-panels to show all available panels.`, case *tcell.EventKey: pressedKey := ev.Rune() // Exit for 'q', ESC, or CTRL-C - if ev.Key() == tcell.KeyESC || ev.Key() == tcell.KeyCtrlC { + if (ev.Key() == tcell.KeyESC && expandedPanel == "") || ev.Key() == tcell.KeyCtrlC { close(exit) return nil } @@ -311,7 +311,7 @@ Use --show-panels to show all available panels.`, if err := refresh(screen, dataFetcher, parsedLayout, false); err != nil { panic(err) } - } else if (pressedKey >= '1' && pressedKey <= '9' && pressedKey <= lastPanelCode) || + } else if ((pressedKey >= '1' && pressedKey <= '9' && pressedKey <= lastPanelCode) || ev.Key() == tcell.KeyESC) || (pressedKey >= 'a' && pressedKey <= 'z' && pressedKey <= lastPanelCode) { updateExpanded(pressedKey, screen, dataFetcher, parsedLayout) } diff --git a/pkg/cmd/panel.go b/pkg/cmd/panel.go index 41c7f79f..86fd77f2 100644 --- a/pkg/cmd/panel.go +++ b/pkg/cmd/panel.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/viper" ) -const providePanelName = "you must provide a panel name" +const providePanelName = "you must provide a single panel name" var panelLayout string diff --git a/pkg/cmd/profile.go b/pkg/cmd/profile.go index 1225f11d..2778d984 100644 --- a/pkg/cmd/profile.go +++ b/pkg/cmd/profile.go @@ -14,7 +14,7 @@ import ( "regexp" ) -const provideProfileName = "you must provide a profile name" +const provideProfileName = "you must provide a single profile name" var ( isValid = regexp.MustCompile(`^[A-Za-z\d-]+$`).MatchString diff --git a/pkg/cmd/proxy.go b/pkg/cmd/proxy.go index daa80222..6c51af8d 100644 --- a/pkg/cmd/proxy.go +++ b/pkg/cmd/proxy.go @@ -20,7 +20,7 @@ import ( ) const ( - provideProxyService = "you must provide a proxy service name" + provideProxyService = "you must provide a single proxy service name" proxyErrorMsg = "unable to find proxy service with service name" tcpString = "tcp" ) @@ -44,7 +44,7 @@ servers for a cluster. You can specify '-o wide' to display addition information return err } - details, err := returnGetProxiesDetails(cmd, tcpString, dataFetcher, connection) + details, err := returnGetProxiesDetails(cmd, tcpString, dataFetcher, connection, "") if err != nil { return err } @@ -127,7 +127,7 @@ all nodes running the proxy service as well as detailed connection information.` } } - err = displayProxyDetails(cmd, dataFetcher, connection, "tcp", serviceResult, proxyResults) + err = displayProxyDetails(cmd, dataFetcher, connection, "tcp", serviceResult, proxyResults, serviceName) if err != nil { return err } @@ -298,7 +298,7 @@ func getProxyNodeIDs(selectedService string, proxiesSummary config.ProxiesSummar return nodeIDs } -func displayProxyDetails(cmd *cobra.Command, dataFetcher fetcher.Fetcher, connection, protocol string, serviceResult, proxyResults []byte) error { +func displayProxyDetails(cmd *cobra.Command, dataFetcher fetcher.Fetcher, connection, protocol string, serviceResult, proxyResults []byte, service string) error { var ( err error finalResult []byte @@ -342,7 +342,7 @@ func displayProxyDetails(cmd *cobra.Command, dataFetcher fetcher.Fetcher, connec cmd.Print(member + "\n") cmd.Print("--------------------" + header + "\n") - value, err = returnGetProxiesDetails(cmd, protocol, dataFetcher, connection) + value, err = returnGetProxiesDetails(cmd, protocol, dataFetcher, connection, service) if err != nil { return err } @@ -352,7 +352,7 @@ func displayProxyDetails(cmd *cobra.Command, dataFetcher fetcher.Fetcher, connec return nil } -func returnGetProxiesDetails(cmd *cobra.Command, protocol string, dataFetcher fetcher.Fetcher, connection string) (string, error) { +func returnGetProxiesDetails(cmd *cobra.Command, protocol string, dataFetcher fetcher.Fetcher, connection string, service string) (string, error) { var sb strings.Builder for { var proxiesSummary = config.ProxiesSummary{} @@ -384,6 +384,16 @@ func returnGetProxiesDetails(cmd *cobra.Command, protocol string, dataFetcher fe if err != nil { return "", utils.GetError("unable to unmarshall proxy result", err) } + if service != "" { + // exclude any proxies that don't equal the service name + finalProxySummary := make([]config.ProxySummary, 0) + for _, v := range proxiesSummary.Proxies { + if v.ServiceName == service { + finalProxySummary = append(finalProxySummary, v) + } + } + proxiesSummary.Proxies = finalProxySummary + } sb.WriteString(FormatProxyServers(proxiesSummary.Proxies, protocol)) } diff --git a/pkg/cmd/reporter.go b/pkg/cmd/reporter.go index 90bfbf0c..62c7589e 100644 --- a/pkg/cmd/reporter.go +++ b/pkg/cmd/reporter.go @@ -26,7 +26,7 @@ const ( reporterIntervalSeconds = "intervalSeconds" reporterOutputPath = "outputPath" reporterUse = "reporter node-id" - provideNodeID = "you must provide a node id" + provideNodeID = "you must provide a single node id" ) var ( @@ -165,7 +165,7 @@ The report name should not include the .xml extension and will have the 'report' 'report-node' will expand to 'reports/report-node.xml'. A HTTP 400 will be returned if the report name is not valid.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, "you must provide a report name") + displayErrorAndExit(cmd, "you must provide a single report name") } return nil }, diff --git a/pkg/cmd/reset_stats.go b/pkg/cmd/reset_stats.go index ba362095..a0311603 100644 --- a/pkg/cmd/reset_stats.go +++ b/pkg/cmd/reset_stats.go @@ -98,7 +98,7 @@ var resetServiceStatsCmd = &cobra.Command{ ValidArgsFunction: completionService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -115,7 +115,7 @@ var resetProxyStatsCmd = &cobra.Command{ ValidArgsFunction: completionProxies, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -148,7 +148,7 @@ var resetFederationStatsCmd = &cobra.Command{ Long: `The 'reset federation-stats' command resets federation statistics for all members or a comma separated list of member IDs.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index 01b2dae5..28ecff19 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -778,7 +778,7 @@ func GetConnectionNameFromContextOrArg() (string, error) { } // otherwise, must be an error - return "", errors.New("you must supply a connection name if you have not set the current context") + return "", errors.New("you must provide a connection name if you have not set the current context") } // GetConnectionAndDataFetcher returns the connection and dataFetcher. diff --git a/pkg/cmd/service.go b/pkg/cmd/service.go index 60d8da59..caa87b0e 100644 --- a/pkg/cmd/service.go +++ b/pkg/cmd/service.go @@ -42,7 +42,6 @@ var ( const ( serviceUse = "service service-name" - provideServiceName = "you must provide a service name" unableToFindService = "unable to find service with service name '%s'" noDistributionsData = "No distributions data is available" serviceUnmarshall = "unable to unmarshall members result" @@ -293,7 +292,7 @@ var getServiceDistributionsCmd = &cobra.Command{ Long: `The 'get service-distributions' command displays partition distributions for a service.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -375,7 +374,7 @@ var getServiceOwnershipCmd = &cobra.Command{ Long: `The 'get service-ownership' command displays partition ownership for a service.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -526,7 +525,7 @@ var getServiceDescriptionCmd = &cobra.Command{ Only available in most recent Coherence versions.`, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -604,7 +603,7 @@ var getServiceMembersCmd = &cobra.Command{ ValidArgsFunction: completionService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -719,7 +718,7 @@ service is a cache service.`, ValidArgsFunction: completionService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -984,7 +983,7 @@ taskHungThresholdMillis or requestTimeoutMillis.`, ValidArgsFunction: completionService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -1103,7 +1102,7 @@ var suspendServiceCmd = &cobra.Command{ ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -1120,7 +1119,7 @@ var resumeServiceCmd = &cobra.Command{ ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -1138,7 +1137,7 @@ Use the shutdown service command for normal service termination.`, ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -1155,7 +1154,7 @@ var startServiceCmd = &cobra.Command{ ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -1173,7 +1172,7 @@ on a cluster member. Shutting down a service is preferred over stopping a servic ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, diff --git a/pkg/cmd/snapshot.go b/pkg/cmd/snapshot.go index 08921f7e..7cb79936 100644 --- a/pkg/cmd/snapshot.go +++ b/pkg/cmd/snapshot.go @@ -31,7 +31,8 @@ var ( ) const ( - provideSnapshot = "you must provide a snapshot name" + provideSnapshot = "you must provide a single snapshot name" + provideService = "you must provide a single service name" snapshotUse = "snapshot snapshot-name" ) @@ -258,7 +259,7 @@ This may lead to the partial or full data loss of the corresponding cache servic ValidArgsFunction: completionPersistenceService, Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { - displayErrorAndExit(cmd, provideServiceName) + displayErrorAndExit(cmd, provideService) } return nil }, @@ -327,7 +328,7 @@ func invokePersistenceOperation(cmd *cobra.Command, operation, snapshotName stri } if serviceName == "" { - return errors.New("you must supply a service name") + return errors.New(provideService) } // if a service was specified then validate if !utils.SliceContains(servicesResult, serviceName) { diff --git a/pkg/cmd/topics.go b/pkg/cmd/topics.go index 52661e7a..71c3f1b4 100644 --- a/pkg/cmd/topics.go +++ b/pkg/cmd/topics.go @@ -22,7 +22,7 @@ import ( ) const ( - SupplyTopicMessage = "you must provide a topic" + SupplyTopicMessage = "you must provide a single topic" NoTopicForService = "there are no topics for service %s" TopicDoesNotExist = "a topic named %s does not exist for service %s" nodeIDMessage = "node id to show channels for" diff --git a/pkg/cmd/utils.go b/pkg/cmd/utils.go index 2ac79072..746cc4cf 100644 --- a/pkg/cmd/utils.go +++ b/pkg/cmd/utils.go @@ -237,7 +237,7 @@ func GetMachineList(dataFetcher fetcher.Fetcher) (map[string]string, error) { machinesMap := make(map[string]string) for _, value := range members.Members { - machineName := value.UnicastAddress + machineName := value.MachineName if _, ok := machinesMap[machineName]; !ok { // does not exist to add it machinesMap[machineName] = value.NodeID diff --git a/pkg/config/config_helper.go b/pkg/config/config_helper.go index e86ff2bd..26fc7198 100644 --- a/pkg/config/config_helper.go +++ b/pkg/config/config_helper.go @@ -209,6 +209,7 @@ type ServiceSummary struct { PartitionsEndangered int32 `json:"partitionsEndangered"` PartitionsVulnerable int32 `json:"partitionsVulnerable"` PartitionsUnbalanced int32 `json:"partitionsUnbalanced"` + RequestPendingCount int32 `json:"requestPendingCount"` StorageEnabled bool `json:"storageEnabled"` QuorumStatus string `json:"quorumStatus"` SeniorMemberID int32 `json:"seniorMemberId"` diff --git a/test/common/common.go b/test/common/common.go index de2e34b6..e557ee8b 100644 --- a/test/common/common.go +++ b/test/common/common.go @@ -1668,15 +1668,15 @@ func RunTestFederationCommands(t *testing.T) { // Get federation and ensure it is idle or paused test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2", configArg, file, - "get", "federation", "destinations", "-c", context.ClusterName) + "get", "federation", "outgoing", "-c", context.ClusterName) // Test JSON - test_utils.EnsureCommandContainsAll(g, t, cliCmd, "\"cluster2\",destinations", configArg, file, + test_utils.EnsureCommandContainsAll(g, t, cliCmd, "\"cluster2\",outgoing", configArg, file, "get", "federation", "all", "-c", context.ClusterName, "-o", "json") // Test JSONPAth test_utils.EnsureCommandContainsAll(g, t, cliCmd, "\"currentBandwidth\",FederatedService", configArg, file, - "get", "federation", "all", "-c", context.ClusterName, "-o", "jsonpath=$.destinations") + "get", "federation", "all", "-c", context.ClusterName, "-o", "jsonpath=$.outgoing") // reset output format to default of TABLE cmd.OutputFormat = constants.TABLE @@ -1694,7 +1694,7 @@ func RunTestFederationCommands(t *testing.T) { // Get federation and ensure it is IDLE as data should have been sent by now // note we have to reset the output format test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2,IDLE", configArg, file, - "get", "federation", "destinations", "-c", context.ClusterName) + "get", "federation", "outgoing", "-c", context.ClusterName) // ensure there is data in the destination cluster test_utils.EnsureCommandContainsAll(g, t, cliCmd, "SERVICE,CACHE,SIZE,federated-1,federated-2,federated-3", @@ -1708,7 +1708,7 @@ func RunTestFederationCommands(t *testing.T) { // Get federation and ensure it is paused test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2,PAUSED", configArg, file, - "get", "federation", "destinations", "-c", context.ClusterName) + "get", "federation", "outgoing", "-c", context.ClusterName) // Stop federation test_utils.EnsureCommandContainsAll(g, t, cliCmd, cmd.OperationCompleted, configArg, file, @@ -1718,7 +1718,7 @@ func RunTestFederationCommands(t *testing.T) { // Get federation and ensure it is stopped test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2,STOPPED", configArg, file, - "get", "federation", "destinations", "-c", context.ClusterName) + "get", "federation", "outgoing", "-c", context.ClusterName) // Start federation test_utils.EnsureCommandContainsAll(g, t, cliCmd, cmd.OperationCompleted, configArg, file, @@ -1728,7 +1728,7 @@ func RunTestFederationCommands(t *testing.T) { // Get federation and ensure it is IDLE as data should have been sent by now test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2,IDLE", configArg, file, - "get", "federation", "destinations", "-c", context.ClusterName) + "get", "federation", "outgoing", "-c", context.ClusterName) // validate we cannot replicate all to an unknown participant test_utils.EnsureCommandErrorContains(g, t, cliCmd, "unable to find participant", configArg, file, @@ -1742,11 +1742,11 @@ func RunTestFederationCommands(t *testing.T) { // get wide output and check for 100.00% test_utils.EnsureCommandContainsAll(g, t, cliCmd, "cluster2,REPLICATE,100.00%", configArg, file, - "get", "federation", "destinations", "-o", "wide", "-c", context.ClusterName) + "get", "federation", "outgoing", "-o", "wide", "-c", context.ClusterName) // test describe federation test_utils.EnsureCommandContainsAll(g, t, cliCmd, "AVG BACKLOG DELAY,AVG APPLY,cluster2", configArg, file, - "describe", "federation", "FederatedService", "-p", "cluster2", "-T", "destinations", "-o", "wide", "-c", context.ClusterName) + "describe", "federation", "FederatedService", "-p", "cluster2", "-T", "outgoing", "-o", "wide", "-c", context.ClusterName) restUrl2 := strings.ReplaceAll(restUrl, "8080", "8081") // populate data in second cluster