get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/jetstream_api.go (about)

     1  // Copyright 2020-2023 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bytes"
    18  	"encoding/json"
    19  	"errors"
    20  	"fmt"
    21  	"math/rand"
    22  	"os"
    23  	"path/filepath"
    24  	"runtime"
    25  	"sort"
    26  	"strconv"
    27  	"strings"
    28  	"sync/atomic"
    29  	"time"
    30  	"unicode"
    31  
    32  	"github.com/nats-io/nuid"
    33  )
    34  
    35  // Request API subjects for JetStream.
    36  const (
    37  	// All API endpoints.
    38  	jsAllAPI = "$JS.API.>"
    39  
    40  	// For constructing JetStream domain prefixes.
    41  	jsDomainAPI = "$JS.%s.API.>"
    42  
    43  	JSApiPrefix = "$JS.API"
    44  
    45  	// JSApiAccountInfo is for obtaining general information about JetStream for this account.
    46  	// Will return JSON response.
    47  	JSApiAccountInfo = "$JS.API.INFO"
    48  
    49  	// JSApiTemplateCreate is the endpoint to create new stream templates.
    50  	// Will return JSON response.
    51  	JSApiTemplateCreate  = "$JS.API.STREAM.TEMPLATE.CREATE.*"
    52  	JSApiTemplateCreateT = "$JS.API.STREAM.TEMPLATE.CREATE.%s"
    53  
    54  	// JSApiTemplates is the endpoint to list all stream template names for this account.
    55  	// Will return JSON response.
    56  	JSApiTemplates = "$JS.API.STREAM.TEMPLATE.NAMES"
    57  
    58  	// JSApiTemplateInfo is for obtaining general information about a named stream template.
    59  	// Will return JSON response.
    60  	JSApiTemplateInfo  = "$JS.API.STREAM.TEMPLATE.INFO.*"
    61  	JSApiTemplateInfoT = "$JS.API.STREAM.TEMPLATE.INFO.%s"
    62  
    63  	// JSApiTemplateDelete is the endpoint to delete stream templates.
    64  	// Will return JSON response.
    65  	JSApiTemplateDelete  = "$JS.API.STREAM.TEMPLATE.DELETE.*"
    66  	JSApiTemplateDeleteT = "$JS.API.STREAM.TEMPLATE.DELETE.%s"
    67  
    68  	// JSApiStreamCreate is the endpoint to create new streams.
    69  	// Will return JSON response.
    70  	JSApiStreamCreate  = "$JS.API.STREAM.CREATE.*"
    71  	JSApiStreamCreateT = "$JS.API.STREAM.CREATE.%s"
    72  
    73  	// JSApiStreamUpdate is the endpoint to update existing streams.
    74  	// Will return JSON response.
    75  	JSApiStreamUpdate  = "$JS.API.STREAM.UPDATE.*"
    76  	JSApiStreamUpdateT = "$JS.API.STREAM.UPDATE.%s"
    77  
    78  	// JSApiStreams is the endpoint to list all stream names for this account.
    79  	// Will return JSON response.
    80  	JSApiStreams = "$JS.API.STREAM.NAMES"
    81  	// JSApiStreamList is the endpoint that will return all detailed stream information
    82  	JSApiStreamList = "$JS.API.STREAM.LIST"
    83  
    84  	// JSApiStreamInfo is for obtaining general information about a named stream.
    85  	// Will return JSON response.
    86  	JSApiStreamInfo  = "$JS.API.STREAM.INFO.*"
    87  	JSApiStreamInfoT = "$JS.API.STREAM.INFO.%s"
    88  
    89  	// JSApiStreamDelete is the endpoint to delete streams.
    90  	// Will return JSON response.
    91  	JSApiStreamDelete  = "$JS.API.STREAM.DELETE.*"
    92  	JSApiStreamDeleteT = "$JS.API.STREAM.DELETE.%s"
    93  
    94  	// JSApiStreamPurge is the endpoint to purge streams.
    95  	// Will return JSON response.
    96  	JSApiStreamPurge  = "$JS.API.STREAM.PURGE.*"
    97  	JSApiStreamPurgeT = "$JS.API.STREAM.PURGE.%s"
    98  
    99  	// JSApiStreamSnapshot is the endpoint to snapshot streams.
   100  	// Will return a stream of chunks with a nil chunk as EOF to
   101  	// the deliver subject. Caller should respond to each chunk
   102  	// with a nil body response for ack flow.
   103  	JSApiStreamSnapshot  = "$JS.API.STREAM.SNAPSHOT.*"
   104  	JSApiStreamSnapshotT = "$JS.API.STREAM.SNAPSHOT.%s"
   105  
   106  	// JSApiStreamRestore is the endpoint to restore a stream from a snapshot.
   107  	// Caller should respond to each chunk with a nil body response.
   108  	JSApiStreamRestore  = "$JS.API.STREAM.RESTORE.*"
   109  	JSApiStreamRestoreT = "$JS.API.STREAM.RESTORE.%s"
   110  
   111  	// JSApiMsgDelete is the endpoint to delete messages from a stream.
   112  	// Will return JSON response.
   113  	JSApiMsgDelete  = "$JS.API.STREAM.MSG.DELETE.*"
   114  	JSApiMsgDeleteT = "$JS.API.STREAM.MSG.DELETE.%s"
   115  
   116  	// JSApiMsgGet is the template for direct requests for a message by its stream sequence number.
   117  	// Will return JSON response.
   118  	JSApiMsgGet  = "$JS.API.STREAM.MSG.GET.*"
   119  	JSApiMsgGetT = "$JS.API.STREAM.MSG.GET.%s"
   120  
   121  	// JSDirectMsgGet is the template for non-api layer direct requests for a message by its stream sequence number or last by subject.
   122  	// Will return the message similar to how a consumer receives the message, no JSON processing.
   123  	// If the message can not be found we will use a status header of 404. If the stream does not exist the client will get a no-responders or timeout.
   124  	JSDirectMsgGet  = "$JS.API.DIRECT.GET.*"
   125  	JSDirectMsgGetT = "$JS.API.DIRECT.GET.%s"
   126  
   127  	// This is a direct version of get last by subject, which will be the dominant pattern for KV access once 2.9 is released.
   128  	// The stream and the key will be part of the subject to allow for no-marshal payloads and subject based security permissions.
   129  	JSDirectGetLastBySubject  = "$JS.API.DIRECT.GET.*.>"
   130  	JSDirectGetLastBySubjectT = "$JS.API.DIRECT.GET.%s.%s"
   131  
   132  	// jsDirectGetPre
   133  	jsDirectGetPre = "$JS.API.DIRECT.GET"
   134  
   135  	// JSApiConsumerCreate is the endpoint to create consumers for streams.
   136  	// This was also the legacy endpoint for ephemeral consumers.
   137  	// It now can take consumer name and optional filter subject, which when part of the subject controls access.
   138  	// Will return JSON response.
   139  	JSApiConsumerCreate    = "$JS.API.CONSUMER.CREATE.*"
   140  	JSApiConsumerCreateT   = "$JS.API.CONSUMER.CREATE.%s"
   141  	JSApiConsumerCreateEx  = "$JS.API.CONSUMER.CREATE.*.>"
   142  	JSApiConsumerCreateExT = "$JS.API.CONSUMER.CREATE.%s.%s.%s"
   143  
   144  	// JSApiDurableCreate is the endpoint to create durable consumers for streams.
   145  	// You need to include the stream and consumer name in the subject.
   146  	JSApiDurableCreate  = "$JS.API.CONSUMER.DURABLE.CREATE.*.*"
   147  	JSApiDurableCreateT = "$JS.API.CONSUMER.DURABLE.CREATE.%s.%s"
   148  
   149  	// JSApiConsumers is the endpoint to list all consumer names for the stream.
   150  	// Will return JSON response.
   151  	JSApiConsumers  = "$JS.API.CONSUMER.NAMES.*"
   152  	JSApiConsumersT = "$JS.API.CONSUMER.NAMES.%s"
   153  
   154  	// JSApiConsumerList is the endpoint that will return all detailed consumer information
   155  	JSApiConsumerList  = "$JS.API.CONSUMER.LIST.*"
   156  	JSApiConsumerListT = "$JS.API.CONSUMER.LIST.%s"
   157  
   158  	// JSApiConsumerInfo is for obtaining general information about a consumer.
   159  	// Will return JSON response.
   160  	JSApiConsumerInfo  = "$JS.API.CONSUMER.INFO.*.*"
   161  	JSApiConsumerInfoT = "$JS.API.CONSUMER.INFO.%s.%s"
   162  
   163  	// JSApiConsumerDelete is the endpoint to delete consumers.
   164  	// Will return JSON response.
   165  	JSApiConsumerDelete  = "$JS.API.CONSUMER.DELETE.*.*"
   166  	JSApiConsumerDeleteT = "$JS.API.CONSUMER.DELETE.%s.%s"
   167  
   168  	// JSApiConsumerPause is the endpoint to pause or unpause consumers.
   169  	// Will return JSON response.
   170  	JSApiConsumerPause  = "$JS.API.CONSUMER.PAUSE.*.*"
   171  	JSApiConsumerPauseT = "$JS.API.CONSUMER.PAUSE.%s.%s"
   172  
   173  	// JSApiRequestNextT is the prefix for the request next message(s) for a consumer in worker/pull mode.
   174  	JSApiRequestNextT = "$JS.API.CONSUMER.MSG.NEXT.%s.%s"
   175  
   176  	// jsRequestNextPre
   177  	jsRequestNextPre = "$JS.API.CONSUMER.MSG.NEXT."
   178  
   179  	// For snapshots and restores. The ack will have additional tokens.
   180  	jsSnapshotAckT    = "$JS.SNAPSHOT.ACK.%s.%s"
   181  	jsRestoreDeliverT = "$JS.SNAPSHOT.RESTORE.%s.%s"
   182  
   183  	// JSApiStreamRemovePeer is the endpoint to remove a peer from a clustered stream and its consumers.
   184  	// Will return JSON response.
   185  	JSApiStreamRemovePeer  = "$JS.API.STREAM.PEER.REMOVE.*"
   186  	JSApiStreamRemovePeerT = "$JS.API.STREAM.PEER.REMOVE.%s"
   187  
   188  	// JSApiStreamLeaderStepDown is the endpoint to have stream leader stepdown.
   189  	// Will return JSON response.
   190  	JSApiStreamLeaderStepDown  = "$JS.API.STREAM.LEADER.STEPDOWN.*"
   191  	JSApiStreamLeaderStepDownT = "$JS.API.STREAM.LEADER.STEPDOWN.%s"
   192  
   193  	// JSApiConsumerLeaderStepDown is the endpoint to have consumer leader stepdown.
   194  	// Will return JSON response.
   195  	JSApiConsumerLeaderStepDown  = "$JS.API.CONSUMER.LEADER.STEPDOWN.*.*"
   196  	JSApiConsumerLeaderStepDownT = "$JS.API.CONSUMER.LEADER.STEPDOWN.%s.%s"
   197  
   198  	// JSApiLeaderStepDown is the endpoint to have our metaleader stepdown.
   199  	// Only works from system account.
   200  	// Will return JSON response.
   201  	JSApiLeaderStepDown = "$JS.API.META.LEADER.STEPDOWN"
   202  
   203  	// JSApiRemoveServer is the endpoint to remove a peer server from the cluster.
   204  	// Only works from system account.
   205  	// Will return JSON response.
   206  	JSApiRemoveServer = "$JS.API.SERVER.REMOVE"
   207  
   208  	// JSApiAccountPurge is the endpoint to purge the js content of an account
   209  	// Only works from system account.
   210  	// Will return JSON response.
   211  	JSApiAccountPurge  = "$JS.API.ACCOUNT.PURGE.*"
   212  	JSApiAccountPurgeT = "$JS.API.ACCOUNT.PURGE.%s"
   213  
   214  	// JSApiServerStreamMove is the endpoint to move streams off a server
   215  	// Only works from system account.
   216  	// Will return JSON response.
   217  	JSApiServerStreamMove  = "$JS.API.ACCOUNT.STREAM.MOVE.*.*"
   218  	JSApiServerStreamMoveT = "$JS.API.ACCOUNT.STREAM.MOVE.%s.%s"
   219  
   220  	// JSApiServerStreamCancelMove is the endpoint to cancel a stream move
   221  	// Only works from system account.
   222  	// Will return JSON response.
   223  	JSApiServerStreamCancelMove  = "$JS.API.ACCOUNT.STREAM.CANCEL_MOVE.*.*"
   224  	JSApiServerStreamCancelMoveT = "$JS.API.ACCOUNT.STREAM.CANCEL_MOVE.%s.%s"
   225  
   226  	// The prefix for system level account API.
   227  	jsAPIAccountPre = "$JS.API.ACCOUNT."
   228  
   229  	// jsAckT is the template for the ack message stream coming back from a consumer
   230  	// when they ACK/NAK, etc a message.
   231  	jsAckT      = "$JS.ACK.%s.%s"
   232  	jsAckPre    = "$JS.ACK."
   233  	jsAckPreLen = len(jsAckPre)
   234  
   235  	// jsFlowControl is for flow control subjects.
   236  	jsFlowControlPre = "$JS.FC."
   237  	// jsFlowControl is for FC responses.
   238  	jsFlowControl = "$JS.FC.%s.%s.*"
   239  
   240  	// JSAdvisoryPrefix is a prefix for all JetStream advisories.
   241  	JSAdvisoryPrefix = "$JS.EVENT.ADVISORY"
   242  
   243  	// JSMetricPrefix is a prefix for all JetStream metrics.
   244  	JSMetricPrefix = "$JS.EVENT.METRIC"
   245  
   246  	// JSMetricConsumerAckPre is a metric containing ack latency.
   247  	JSMetricConsumerAckPre = "$JS.EVENT.METRIC.CONSUMER.ACK"
   248  
   249  	// JSAdvisoryConsumerMaxDeliveryExceedPre is a notification published when a message exceeds its delivery threshold.
   250  	JSAdvisoryConsumerMaxDeliveryExceedPre = "$JS.EVENT.ADVISORY.CONSUMER.MAX_DELIVERIES"
   251  
   252  	// JSAdvisoryConsumerMsgNakPre is a notification published when a message has been naked
   253  	JSAdvisoryConsumerMsgNakPre = "$JS.EVENT.ADVISORY.CONSUMER.MSG_NAKED"
   254  
   255  	// JSAdvisoryConsumerMsgTerminatedPre is a notification published when a message has been terminated.
   256  	JSAdvisoryConsumerMsgTerminatedPre = "$JS.EVENT.ADVISORY.CONSUMER.MSG_TERMINATED"
   257  
   258  	// JSAdvisoryStreamCreatedPre notification that a stream was created.
   259  	JSAdvisoryStreamCreatedPre = "$JS.EVENT.ADVISORY.STREAM.CREATED"
   260  
   261  	// JSAdvisoryStreamDeletedPre notification that a stream was deleted.
   262  	JSAdvisoryStreamDeletedPre = "$JS.EVENT.ADVISORY.STREAM.DELETED"
   263  
   264  	// JSAdvisoryStreamUpdatedPre notification that a stream was updated.
   265  	JSAdvisoryStreamUpdatedPre = "$JS.EVENT.ADVISORY.STREAM.UPDATED"
   266  
   267  	// JSAdvisoryConsumerCreatedPre notification that a template created.
   268  	JSAdvisoryConsumerCreatedPre = "$JS.EVENT.ADVISORY.CONSUMER.CREATED"
   269  
   270  	// JSAdvisoryConsumerDeletedPre notification that a template deleted.
   271  	JSAdvisoryConsumerDeletedPre = "$JS.EVENT.ADVISORY.CONSUMER.DELETED"
   272  
   273  	// JSAdvisoryConsumerPausePre notification that a consumer paused/unpaused.
   274  	JSAdvisoryConsumerPausePre = "$JS.EVENT.ADVISORY.CONSUMER.PAUSE"
   275  
   276  	// JSAdvisoryStreamSnapshotCreatePre notification that a snapshot was created.
   277  	JSAdvisoryStreamSnapshotCreatePre = "$JS.EVENT.ADVISORY.STREAM.SNAPSHOT_CREATE"
   278  
   279  	// JSAdvisoryStreamSnapshotCompletePre notification that a snapshot was completed.
   280  	JSAdvisoryStreamSnapshotCompletePre = "$JS.EVENT.ADVISORY.STREAM.SNAPSHOT_COMPLETE"
   281  
   282  	// JSAdvisoryStreamRestoreCreatePre notification that a restore was start.
   283  	JSAdvisoryStreamRestoreCreatePre = "$JS.EVENT.ADVISORY.STREAM.RESTORE_CREATE"
   284  
   285  	// JSAdvisoryStreamRestoreCompletePre notification that a restore was completed.
   286  	JSAdvisoryStreamRestoreCompletePre = "$JS.EVENT.ADVISORY.STREAM.RESTORE_COMPLETE"
   287  
   288  	// JSAdvisoryDomainLeaderElectedPre notification that a jetstream domain has elected a leader.
   289  	JSAdvisoryDomainLeaderElected = "$JS.EVENT.ADVISORY.DOMAIN.LEADER_ELECTED"
   290  
   291  	// JSAdvisoryStreamLeaderElectedPre notification that a replicated stream has elected a leader.
   292  	JSAdvisoryStreamLeaderElectedPre = "$JS.EVENT.ADVISORY.STREAM.LEADER_ELECTED"
   293  
   294  	// JSAdvisoryStreamQuorumLostPre notification that a stream and its consumers are stalled.
   295  	JSAdvisoryStreamQuorumLostPre = "$JS.EVENT.ADVISORY.STREAM.QUORUM_LOST"
   296  
   297  	// JSAdvisoryConsumerLeaderElectedPre notification that a replicated consumer has elected a leader.
   298  	JSAdvisoryConsumerLeaderElectedPre = "$JS.EVENT.ADVISORY.CONSUMER.LEADER_ELECTED"
   299  
   300  	// JSAdvisoryConsumerQuorumLostPre notification that a consumer is stalled.
   301  	JSAdvisoryConsumerQuorumLostPre = "$JS.EVENT.ADVISORY.CONSUMER.QUORUM_LOST"
   302  
   303  	// JSAdvisoryServerOutOfStorage notification that a server has no more storage.
   304  	JSAdvisoryServerOutOfStorage = "$JS.EVENT.ADVISORY.SERVER.OUT_OF_STORAGE"
   305  
   306  	// JSAdvisoryServerRemoved notification that a server has been removed from the system.
   307  	JSAdvisoryServerRemoved = "$JS.EVENT.ADVISORY.SERVER.REMOVED"
   308  
   309  	// JSAuditAdvisory is a notification about JetStream API access.
   310  	// FIXME - Add in details about who..
   311  	JSAuditAdvisory = "$JS.EVENT.ADVISORY.API"
   312  )
   313  
   314  var denyAllClientJs = []string{jsAllAPI, "$KV.>", "$OBJ.>"}
   315  var denyAllJs = []string{jscAllSubj, raftAllSubj, jsAllAPI, "$KV.>", "$OBJ.>"}
   316  
   317  func generateJSMappingTable(domain string) map[string]string {
   318  	mappings := map[string]string{}
   319  	// This set of mappings is very very very ugly.
   320  	// It is a consequence of what we defined the domain prefix to be "$JS.domain.API" and it's mapping to "$JS.API"
   321  	// For optics $KV and $OBJ where made to be independent subject spaces.
   322  	// As materialized views of JS, they did not simply extend that subject space to say "$JS.API.KV" "$JS.API.OBJ"
   323  	// This is very unfortunate!!!
   324  	// Furthermore, it seemed bad to require different domain prefixes for JS/KV/OBJ.
   325  	// Especially since the actual API for say KV, does use stream create from JS.
   326  	// To avoid overlaps KV and OBJ views append the prefix to their API.
   327  	// (Replacing $KV with the prefix allows users to create collisions with say the bucket name)
   328  	// This mapping therefore needs to have extra token so that the mapping can properly discern between $JS, $KV, $OBJ
   329  	for srcMappingSuffix, to := range map[string]string{
   330  		"INFO":       JSApiAccountInfo,
   331  		"STREAM.>":   "$JS.API.STREAM.>",
   332  		"CONSUMER.>": "$JS.API.CONSUMER.>",
   333  		"DIRECT.>":   "$JS.API.DIRECT.>",
   334  		"META.>":     "$JS.API.META.>",
   335  		"SERVER.>":   "$JS.API.SERVER.>",
   336  		"ACCOUNT.>":  "$JS.API.ACCOUNT.>",
   337  		"$KV.>":      "$KV.>",
   338  		"$OBJ.>":     "$OBJ.>",
   339  	} {
   340  		mappings[fmt.Sprintf("$JS.%s.API.%s", domain, srcMappingSuffix)] = to
   341  	}
   342  	return mappings
   343  }
   344  
   345  // JSMaxDescription is the maximum description length for streams and consumers.
   346  const JSMaxDescriptionLen = 4 * 1024
   347  
   348  // JSMaxMetadataLen is the maximum length for streams and consumers metadata map.
   349  // It's calculated by summing length of all keys and values.
   350  const JSMaxMetadataLen = 128 * 1024
   351  
   352  // JSMaxNameLen is the maximum name lengths for streams, consumers and templates.
   353  // Picked 255 as it seems to be a widely used file name limit
   354  const JSMaxNameLen = 255
   355  
   356  // Responses for API calls.
   357  
   358  // ApiResponse is a standard response from the JetStream JSON API
   359  type ApiResponse struct {
   360  	Type  string    `json:"type"`
   361  	Error *ApiError `json:"error,omitempty"`
   362  }
   363  
   364  const JSApiSystemResponseType = "io.nats.jetstream.api.v1.system_response"
   365  
   366  // When passing back to the clients generalize store failures.
   367  var (
   368  	errStreamStoreFailed   = errors.New("error creating store for stream")
   369  	errConsumerStoreFailed = errors.New("error creating store for consumer")
   370  )
   371  
   372  // ToError checks if the response has a error and if it does converts it to an error avoiding
   373  // the pitfalls described by https://yourbasic.org/golang/gotcha-why-nil-error-not-equal-nil/
   374  func (r *ApiResponse) ToError() error {
   375  	if r.Error == nil {
   376  		return nil
   377  	}
   378  
   379  	return r.Error
   380  }
   381  
   382  const JSApiOverloadedType = "io.nats.jetstream.api.v1.system_overloaded"
   383  
   384  // ApiPaged includes variables used to create paged responses from the JSON API
   385  type ApiPaged struct {
   386  	Total  int `json:"total"`
   387  	Offset int `json:"offset"`
   388  	Limit  int `json:"limit"`
   389  }
   390  
   391  // ApiPagedRequest includes parameters allowing specific pages to be requests from APIs responding with ApiPaged
   392  type ApiPagedRequest struct {
   393  	Offset int `json:"offset"`
   394  }
   395  
   396  // JSApiAccountInfoResponse reports back information on jetstream for this account.
   397  type JSApiAccountInfoResponse struct {
   398  	ApiResponse
   399  	*JetStreamAccountStats
   400  }
   401  
   402  const JSApiAccountInfoResponseType = "io.nats.jetstream.api.v1.account_info_response"
   403  
   404  // JSApiStreamCreateResponse stream creation.
   405  type JSApiStreamCreateResponse struct {
   406  	ApiResponse
   407  	*StreamInfo
   408  	DidCreate bool `json:"did_create,omitempty"`
   409  }
   410  
   411  const JSApiStreamCreateResponseType = "io.nats.jetstream.api.v1.stream_create_response"
   412  
   413  // JSApiStreamDeleteResponse stream removal.
   414  type JSApiStreamDeleteResponse struct {
   415  	ApiResponse
   416  	Success bool `json:"success,omitempty"`
   417  }
   418  
   419  const JSApiStreamDeleteResponseType = "io.nats.jetstream.api.v1.stream_delete_response"
   420  
   421  // JSMaxSubjectDetails The limit of the number of subject details we will send in a stream info response.
   422  const JSMaxSubjectDetails = 100_000
   423  
   424  type JSApiStreamInfoRequest struct {
   425  	ApiPagedRequest
   426  	DeletedDetails bool   `json:"deleted_details,omitempty"`
   427  	SubjectsFilter string `json:"subjects_filter,omitempty"`
   428  }
   429  
   430  type JSApiStreamInfoResponse struct {
   431  	ApiResponse
   432  	ApiPaged
   433  	*StreamInfo
   434  }
   435  
   436  const JSApiStreamInfoResponseType = "io.nats.jetstream.api.v1.stream_info_response"
   437  
   438  // JSApiNamesLimit is the maximum entries we will return for streams or consumers lists.
   439  // TODO(dlc) - with header or request support could request chunked response.
   440  const JSApiNamesLimit = 1024
   441  const JSApiListLimit = 256
   442  
   443  type JSApiStreamNamesRequest struct {
   444  	ApiPagedRequest
   445  	// These are filters that can be applied to the list.
   446  	Subject string `json:"subject,omitempty"`
   447  }
   448  
   449  // JSApiStreamNamesResponse list of streams.
   450  // A nil request is valid and means all streams.
   451  type JSApiStreamNamesResponse struct {
   452  	ApiResponse
   453  	ApiPaged
   454  	Streams []string `json:"streams"`
   455  }
   456  
   457  const JSApiStreamNamesResponseType = "io.nats.jetstream.api.v1.stream_names_response"
   458  
   459  type JSApiStreamListRequest struct {
   460  	ApiPagedRequest
   461  	// These are filters that can be applied to the list.
   462  	Subject string `json:"subject,omitempty"`
   463  }
   464  
   465  // JSApiStreamListResponse list of detailed stream information.
   466  // A nil request is valid and means all streams.
   467  type JSApiStreamListResponse struct {
   468  	ApiResponse
   469  	ApiPaged
   470  	Streams []*StreamInfo `json:"streams"`
   471  	Missing []string      `json:"missing,omitempty"`
   472  }
   473  
   474  const JSApiStreamListResponseType = "io.nats.jetstream.api.v1.stream_list_response"
   475  
   476  // JSApiStreamPurgeRequest is optional request information to the purge API.
   477  // Subject will filter the purge request to only messages that match the subject, which can have wildcards.
   478  // Sequence will purge up to but not including this sequence and can be combined with subject filtering.
   479  // Keep will specify how many messages to keep. This can also be combined with subject filtering.
   480  // Note that Sequence and Keep are mutually exclusive, so both can not be set at the same time.
   481  type JSApiStreamPurgeRequest struct {
   482  	// Purge up to but not including sequence.
   483  	Sequence uint64 `json:"seq,omitempty"`
   484  	// Subject to match against messages for the purge command.
   485  	Subject string `json:"filter,omitempty"`
   486  	// Number of messages to keep.
   487  	Keep uint64 `json:"keep,omitempty"`
   488  }
   489  
   490  type JSApiStreamPurgeResponse struct {
   491  	ApiResponse
   492  	Success bool   `json:"success,omitempty"`
   493  	Purged  uint64 `json:"purged"`
   494  }
   495  
   496  const JSApiStreamPurgeResponseType = "io.nats.jetstream.api.v1.stream_purge_response"
   497  
   498  // JSApiStreamUpdateResponse for updating a stream.
   499  type JSApiStreamUpdateResponse struct {
   500  	ApiResponse
   501  	*StreamInfo
   502  }
   503  
   504  const JSApiStreamUpdateResponseType = "io.nats.jetstream.api.v1.stream_update_response"
   505  
   506  // JSApiMsgDeleteRequest delete message request.
   507  type JSApiMsgDeleteRequest struct {
   508  	Seq     uint64 `json:"seq"`
   509  	NoErase bool   `json:"no_erase,omitempty"`
   510  }
   511  
   512  type JSApiMsgDeleteResponse struct {
   513  	ApiResponse
   514  	Success bool `json:"success,omitempty"`
   515  }
   516  
   517  const JSApiMsgDeleteResponseType = "io.nats.jetstream.api.v1.stream_msg_delete_response"
   518  
   519  type JSApiStreamSnapshotRequest struct {
   520  	// Subject to deliver the chunks to for the snapshot.
   521  	DeliverSubject string `json:"deliver_subject"`
   522  	// Do not include consumers in the snapshot.
   523  	NoConsumers bool `json:"no_consumers,omitempty"`
   524  	// Optional chunk size preference.
   525  	// Best to just let server select.
   526  	ChunkSize int `json:"chunk_size,omitempty"`
   527  	// Check all message's checksums prior to snapshot.
   528  	CheckMsgs bool `json:"jsck,omitempty"`
   529  }
   530  
   531  // JSApiStreamSnapshotResponse is the direct response to the snapshot request.
   532  type JSApiStreamSnapshotResponse struct {
   533  	ApiResponse
   534  	// Configuration of the given stream.
   535  	Config *StreamConfig `json:"config,omitempty"`
   536  	// Current State for the given stream.
   537  	State *StreamState `json:"state,omitempty"`
   538  }
   539  
   540  const JSApiStreamSnapshotResponseType = "io.nats.jetstream.api.v1.stream_snapshot_response"
   541  
   542  // JSApiStreamRestoreRequest is the required restore request.
   543  type JSApiStreamRestoreRequest struct {
   544  	// Configuration of the given stream.
   545  	Config StreamConfig `json:"config"`
   546  	// Current State for the given stream.
   547  	State StreamState `json:"state"`
   548  }
   549  
   550  // JSApiStreamRestoreResponse is the direct response to the restore request.
   551  type JSApiStreamRestoreResponse struct {
   552  	ApiResponse
   553  	// Subject to deliver the chunks to for the snapshot restore.
   554  	DeliverSubject string `json:"deliver_subject"`
   555  }
   556  
   557  const JSApiStreamRestoreResponseType = "io.nats.jetstream.api.v1.stream_restore_response"
   558  
   559  // JSApiStreamRemovePeerRequest is the required remove peer request.
   560  type JSApiStreamRemovePeerRequest struct {
   561  	// Server name of the peer to be removed.
   562  	Peer string `json:"peer"`
   563  }
   564  
   565  // JSApiStreamRemovePeerResponse is the response to a remove peer request.
   566  type JSApiStreamRemovePeerResponse struct {
   567  	ApiResponse
   568  	Success bool `json:"success,omitempty"`
   569  }
   570  
   571  const JSApiStreamRemovePeerResponseType = "io.nats.jetstream.api.v1.stream_remove_peer_response"
   572  
   573  // JSApiStreamLeaderStepDownResponse is the response to a leader stepdown request.
   574  type JSApiStreamLeaderStepDownResponse struct {
   575  	ApiResponse
   576  	Success bool `json:"success,omitempty"`
   577  }
   578  
   579  const JSApiStreamLeaderStepDownResponseType = "io.nats.jetstream.api.v1.stream_leader_stepdown_response"
   580  
   581  // JSApiConsumerLeaderStepDownResponse is the response to a consumer leader stepdown request.
   582  type JSApiConsumerLeaderStepDownResponse struct {
   583  	ApiResponse
   584  	Success bool `json:"success,omitempty"`
   585  }
   586  
   587  const JSApiConsumerLeaderStepDownResponseType = "io.nats.jetstream.api.v1.consumer_leader_stepdown_response"
   588  
   589  // JSApiLeaderStepdownRequest allows placement control over the meta leader placement.
   590  type JSApiLeaderStepdownRequest struct {
   591  	Placement *Placement `json:"placement,omitempty"`
   592  }
   593  
   594  // JSApiLeaderStepDownResponse is the response to a meta leader stepdown request.
   595  type JSApiLeaderStepDownResponse struct {
   596  	ApiResponse
   597  	Success bool `json:"success,omitempty"`
   598  }
   599  
   600  const JSApiLeaderStepDownResponseType = "io.nats.jetstream.api.v1.meta_leader_stepdown_response"
   601  
   602  // JSApiMetaServerRemoveRequest will remove a peer from the meta group.
   603  type JSApiMetaServerRemoveRequest struct {
   604  	// Server name of the peer to be removed.
   605  	Server string `json:"peer"`
   606  	// Peer ID of the peer to be removed. If specified this is used
   607  	// instead of the server name.
   608  	Peer string `json:"peer_id,omitempty"`
   609  }
   610  
   611  // JSApiMetaServerRemoveResponse is the response to a peer removal request in the meta group.
   612  type JSApiMetaServerRemoveResponse struct {
   613  	ApiResponse
   614  	Success bool `json:"success,omitempty"`
   615  }
   616  
   617  const JSApiMetaServerRemoveResponseType = "io.nats.jetstream.api.v1.meta_server_remove_response"
   618  
   619  // JSApiMetaServerStreamMoveRequest will move a stream on a server to another
   620  // response to this will come as JSApiStreamUpdateResponse/JSApiStreamUpdateResponseType
   621  type JSApiMetaServerStreamMoveRequest struct {
   622  	// Server name of the peer to be evacuated.
   623  	Server string `json:"server,omitempty"`
   624  	// Cluster the server is in
   625  	Cluster string `json:"cluster,omitempty"`
   626  	// Domain the sever is in
   627  	Domain string `json:"domain,omitempty"`
   628  	// Ephemeral placement tags for the move
   629  	Tags []string `json:"tags,omitempty"`
   630  }
   631  
   632  const JSApiAccountPurgeResponseType = "io.nats.jetstream.api.v1.account_purge_response"
   633  
   634  // JSApiAccountPurgeResponse is the response to a purge request in the meta group.
   635  type JSApiAccountPurgeResponse struct {
   636  	ApiResponse
   637  	Initiated bool `json:"initiated,omitempty"`
   638  }
   639  
   640  // JSApiMsgGetRequest get a message request.
   641  type JSApiMsgGetRequest struct {
   642  	Seq     uint64 `json:"seq,omitempty"`
   643  	LastFor string `json:"last_by_subj,omitempty"`
   644  	NextFor string `json:"next_by_subj,omitempty"`
   645  
   646  	// Batch support. Used to request more then one msg at a time.
   647  	// Can be used with simple starting seq, but also NextFor with wildcards.
   648  	Batch int `json:"batch,omitempty"`
   649  	// This will make sure we limit how much data we blast out. If not set we will
   650  	// inherit the slow consumer default max setting of the server. Default is MAX_PENDING_SIZE.
   651  	MaxBytes int `json:"max_bytes,omitempty"`
   652  
   653  	// Multiple response support. Will get the last msgs matching the subjects. These can include wildcards.
   654  	MultiLastFor []string `json:"multi_last,omitempty"`
   655  	// Only return messages up to this sequence. If not set, will be last sequence for the stream.
   656  	UpToSeq uint64 `json:"up_to_seq,omitempty"`
   657  	// Only return messages up to this time.
   658  	UpToTime *time.Time `json:"up_to_time,omitempty"`
   659  }
   660  
   661  type JSApiMsgGetResponse struct {
   662  	ApiResponse
   663  	Message *StoredMsg `json:"message,omitempty"`
   664  }
   665  
   666  const JSApiMsgGetResponseType = "io.nats.jetstream.api.v1.stream_msg_get_response"
   667  
   668  // JSWaitQueueDefaultMax is the default max number of outstanding requests for pull consumers.
   669  const JSWaitQueueDefaultMax = 512
   670  
   671  type JSApiConsumerCreateResponse struct {
   672  	ApiResponse
   673  	*ConsumerInfo
   674  }
   675  
   676  const JSApiConsumerCreateResponseType = "io.nats.jetstream.api.v1.consumer_create_response"
   677  
   678  type JSApiConsumerDeleteResponse struct {
   679  	ApiResponse
   680  	Success bool `json:"success,omitempty"`
   681  }
   682  
   683  const JSApiConsumerDeleteResponseType = "io.nats.jetstream.api.v1.consumer_delete_response"
   684  
   685  type JSApiConsumerPauseRequest struct {
   686  	PauseUntil time.Time `json:"pause_until,omitempty"`
   687  }
   688  
   689  const JSApiConsumerPauseResponseType = "io.nats.jetstream.api.v1.consumer_pause_response"
   690  
   691  type JSApiConsumerPauseResponse struct {
   692  	ApiResponse
   693  	Paused         bool          `json:"paused"`
   694  	PauseUntil     time.Time     `json:"pause_until"`
   695  	PauseRemaining time.Duration `json:"pause_remaining,omitempty"`
   696  }
   697  
   698  type JSApiConsumerInfoResponse struct {
   699  	ApiResponse
   700  	*ConsumerInfo
   701  }
   702  
   703  const JSApiConsumerInfoResponseType = "io.nats.jetstream.api.v1.consumer_info_response"
   704  
   705  type JSApiConsumersRequest struct {
   706  	ApiPagedRequest
   707  }
   708  
   709  type JSApiConsumerNamesResponse struct {
   710  	ApiResponse
   711  	ApiPaged
   712  	Consumers []string `json:"consumers"`
   713  }
   714  
   715  const JSApiConsumerNamesResponseType = "io.nats.jetstream.api.v1.consumer_names_response"
   716  
   717  type JSApiConsumerListResponse struct {
   718  	ApiResponse
   719  	ApiPaged
   720  	Consumers []*ConsumerInfo `json:"consumers"`
   721  	Missing   []string        `json:"missing,omitempty"`
   722  }
   723  
   724  const JSApiConsumerListResponseType = "io.nats.jetstream.api.v1.consumer_list_response"
   725  
   726  // JSApiConsumerGetNextRequest is for getting next messages for pull based consumers.
   727  type JSApiConsumerGetNextRequest struct {
   728  	Expires   time.Duration `json:"expires,omitempty"`
   729  	Batch     int           `json:"batch,omitempty"`
   730  	MaxBytes  int           `json:"max_bytes,omitempty"`
   731  	NoWait    bool          `json:"no_wait,omitempty"`
   732  	Heartbeat time.Duration `json:"idle_heartbeat,omitempty"`
   733  }
   734  
   735  // JSApiStreamTemplateCreateResponse for creating templates.
   736  type JSApiStreamTemplateCreateResponse struct {
   737  	ApiResponse
   738  	*StreamTemplateInfo
   739  }
   740  
   741  const JSApiStreamTemplateCreateResponseType = "io.nats.jetstream.api.v1.stream_template_create_response"
   742  
   743  type JSApiStreamTemplateDeleteResponse struct {
   744  	ApiResponse
   745  	Success bool `json:"success,omitempty"`
   746  }
   747  
   748  const JSApiStreamTemplateDeleteResponseType = "io.nats.jetstream.api.v1.stream_template_delete_response"
   749  
   750  // JSApiStreamTemplateInfoResponse for information about stream templates.
   751  type JSApiStreamTemplateInfoResponse struct {
   752  	ApiResponse
   753  	*StreamTemplateInfo
   754  }
   755  
   756  const JSApiStreamTemplateInfoResponseType = "io.nats.jetstream.api.v1.stream_template_info_response"
   757  
   758  type JSApiStreamTemplatesRequest struct {
   759  	ApiPagedRequest
   760  }
   761  
   762  // JSApiStreamTemplateNamesResponse list of templates
   763  type JSApiStreamTemplateNamesResponse struct {
   764  	ApiResponse
   765  	ApiPaged
   766  	Templates []string `json:"streams"`
   767  }
   768  
   769  const JSApiStreamTemplateNamesResponseType = "io.nats.jetstream.api.v1.stream_template_names_response"
   770  
   771  // Structure that holds state for a JetStream API request that is processed
   772  // in a separate long-lived go routine. This is to avoid possibly blocking
   773  // ROUTE and GATEWAY connections.
   774  type jsAPIRoutedReq struct {
   775  	jsub    *subscription
   776  	sub     *subscription
   777  	acc     *Account
   778  	subject string
   779  	reply   string
   780  	msg     []byte
   781  	pa      pubArg
   782  }
   783  
   784  func (js *jetStream) apiDispatch(sub *subscription, c *client, acc *Account, subject, reply string, rmsg []byte) {
   785  	// Ignore system level directives meta stepdown and peer remove requests here.
   786  	if subject == JSApiLeaderStepDown ||
   787  		subject == JSApiRemoveServer ||
   788  		strings.HasPrefix(subject, jsAPIAccountPre) {
   789  		return
   790  	}
   791  	// No lock needed, those are immutable.
   792  	s, rr := js.srv, js.apiSubs.Match(subject)
   793  
   794  	hdr, msg := c.msgParts(rmsg)
   795  	if len(getHeader(ClientInfoHdr, hdr)) == 0 {
   796  		// Check if this is the system account. We will let these through for the account info only.
   797  		sacc := s.SystemAccount()
   798  		if sacc != acc {
   799  			return
   800  		}
   801  		if subject != JSApiAccountInfo {
   802  			// Only respond from the initial server entry to the NATS system.
   803  			if c.kind == CLIENT || c.kind == LEAF {
   804  				var resp = ApiResponse{
   805  					Type:  JSApiSystemResponseType,
   806  					Error: NewJSNotEnabledForAccountError(),
   807  				}
   808  				s.sendAPIErrResponse(nil, acc, subject, reply, string(msg), s.jsonResponse(&resp))
   809  			}
   810  			return
   811  		}
   812  	}
   813  
   814  	// Short circuit for no interest.
   815  	if len(rr.psubs)+len(rr.qsubs) == 0 {
   816  		if (c.kind == CLIENT || c.kind == LEAF) && acc != s.SystemAccount() {
   817  			ci, acc, _, _, _ := s.getRequestInfo(c, rmsg)
   818  			var resp = ApiResponse{
   819  				Type:  JSApiSystemResponseType,
   820  				Error: NewJSBadRequestError(),
   821  			}
   822  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
   823  		}
   824  		return
   825  	}
   826  
   827  	// We should only have psubs and only 1 per result.
   828  	if len(rr.psubs) != 1 {
   829  		s.Warnf("Malformed JetStream API Request: [%s] %q", subject, rmsg)
   830  		if c.kind == CLIENT || c.kind == LEAF {
   831  			ci, acc, _, _, _ := s.getRequestInfo(c, rmsg)
   832  			var resp = ApiResponse{
   833  				Type:  JSApiSystemResponseType,
   834  				Error: NewJSBadRequestError(),
   835  			}
   836  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
   837  		}
   838  		return
   839  	}
   840  	jsub := rr.psubs[0]
   841  
   842  	// If this is directly from a client connection ok to do in place.
   843  	if c.kind != ROUTER && c.kind != GATEWAY && c.kind != LEAF {
   844  		start := time.Now()
   845  		jsub.icb(sub, c, acc, subject, reply, rmsg)
   846  		if dur := time.Since(start); dur >= readLoopReportThreshold {
   847  			s.Warnf("Internal subscription on %q took too long: %v", subject, dur)
   848  		}
   849  		return
   850  	}
   851  
   852  	// If we are here we have received this request over a non-client connection.
   853  	// We need to make sure not to block. We will send the request to a long-lived
   854  	// pool of go routines.
   855  
   856  	// Increment inflight. Do this before queueing.
   857  	atomic.AddInt64(&js.apiInflight, 1)
   858  
   859  	// Copy the state. Note the JSAPI only uses the hdr index to piece apart the
   860  	// header from the msg body. No other references are needed.
   861  	// Check pending and warn if getting backed up.
   862  	const warnThresh = 32
   863  	pending := s.jsAPIRoutedReqs.push(&jsAPIRoutedReq{jsub, sub, acc, subject, reply, copyBytes(rmsg), c.pa})
   864  	if pending > warnThresh {
   865  		s.RateLimitWarnf("JetStream request queue has high pending count: %d", pending)
   866  	}
   867  }
   868  
   869  func (s *Server) processJSAPIRoutedRequests() {
   870  	defer s.grWG.Done()
   871  
   872  	s.mu.RLock()
   873  	queue := s.jsAPIRoutedReqs
   874  	client := &client{srv: s, kind: JETSTREAM}
   875  	s.mu.RUnlock()
   876  
   877  	js := s.getJetStream()
   878  
   879  	for {
   880  		select {
   881  		case <-queue.ch:
   882  			reqs := queue.pop()
   883  			for _, r := range reqs {
   884  				client.pa = r.pa
   885  				start := time.Now()
   886  				r.jsub.icb(r.sub, client, r.acc, r.subject, r.reply, r.msg)
   887  				if dur := time.Since(start); dur >= readLoopReportThreshold {
   888  					s.Warnf("Internal subscription on %q took too long: %v", r.subject, dur)
   889  				}
   890  				atomic.AddInt64(&js.apiInflight, -1)
   891  			}
   892  			queue.recycle(&reqs)
   893  		case <-s.quitCh:
   894  			return
   895  		}
   896  	}
   897  }
   898  
   899  func (s *Server) setJetStreamExportSubs() error {
   900  	js := s.getJetStream()
   901  	if js == nil {
   902  		return NewJSNotEnabledError()
   903  	}
   904  
   905  	// Start the go routine that will process API requests received by the
   906  	// subscription below when they are coming from routes, etc..
   907  	const maxProcs = 16
   908  	mp := runtime.GOMAXPROCS(0)
   909  	// Cap at 16 max for now on larger core setups.
   910  	if mp > maxProcs {
   911  		mp = maxProcs
   912  	}
   913  	s.jsAPIRoutedReqs = newIPQueue[*jsAPIRoutedReq](s, "Routed JS API Requests")
   914  	for i := 0; i < mp; i++ {
   915  		s.startGoRoutine(s.processJSAPIRoutedRequests)
   916  	}
   917  
   918  	// This is the catch all now for all JetStream API calls.
   919  	if _, err := s.sysSubscribe(jsAllAPI, js.apiDispatch); err != nil {
   920  		return err
   921  	}
   922  
   923  	if err := s.SystemAccount().AddServiceExport(jsAllAPI, nil); err != nil {
   924  		s.Warnf("Error setting up jetstream service exports: %v", err)
   925  		return err
   926  	}
   927  
   928  	// API handles themselves.
   929  	pairs := []struct {
   930  		subject string
   931  		handler msgHandler
   932  	}{
   933  		{JSApiAccountInfo, s.jsAccountInfoRequest},
   934  		{JSApiTemplateCreate, s.jsTemplateCreateRequest},
   935  		{JSApiTemplates, s.jsTemplateNamesRequest},
   936  		{JSApiTemplateInfo, s.jsTemplateInfoRequest},
   937  		{JSApiTemplateDelete, s.jsTemplateDeleteRequest},
   938  		{JSApiStreamCreate, s.jsStreamCreateRequest},
   939  		{JSApiStreamUpdate, s.jsStreamUpdateRequest},
   940  		{JSApiStreams, s.jsStreamNamesRequest},
   941  		{JSApiStreamList, s.jsStreamListRequest},
   942  		{JSApiStreamInfo, s.jsStreamInfoRequest},
   943  		{JSApiStreamDelete, s.jsStreamDeleteRequest},
   944  		{JSApiStreamPurge, s.jsStreamPurgeRequest},
   945  		{JSApiStreamSnapshot, s.jsStreamSnapshotRequest},
   946  		{JSApiStreamRestore, s.jsStreamRestoreRequest},
   947  		{JSApiStreamRemovePeer, s.jsStreamRemovePeerRequest},
   948  		{JSApiStreamLeaderStepDown, s.jsStreamLeaderStepDownRequest},
   949  		{JSApiConsumerLeaderStepDown, s.jsConsumerLeaderStepDownRequest},
   950  		{JSApiMsgDelete, s.jsMsgDeleteRequest},
   951  		{JSApiMsgGet, s.jsMsgGetRequest},
   952  		{JSApiConsumerCreateEx, s.jsConsumerCreateRequest},
   953  		{JSApiConsumerCreate, s.jsConsumerCreateRequest},
   954  		{JSApiDurableCreate, s.jsConsumerCreateRequest},
   955  		{JSApiConsumers, s.jsConsumerNamesRequest},
   956  		{JSApiConsumerList, s.jsConsumerListRequest},
   957  		{JSApiConsumerInfo, s.jsConsumerInfoRequest},
   958  		{JSApiConsumerDelete, s.jsConsumerDeleteRequest},
   959  		{JSApiConsumerPause, s.jsConsumerPauseRequest},
   960  	}
   961  
   962  	js.mu.Lock()
   963  	defer js.mu.Unlock()
   964  
   965  	for _, p := range pairs {
   966  		sub := &subscription{subject: []byte(p.subject), icb: p.handler}
   967  		if err := js.apiSubs.Insert(sub); err != nil {
   968  			return err
   969  		}
   970  	}
   971  
   972  	return nil
   973  }
   974  
   975  func (s *Server) sendAPIResponse(ci *ClientInfo, acc *Account, subject, reply, request, response string) {
   976  	acc.trackAPI()
   977  	if reply != _EMPTY_ {
   978  		s.sendInternalAccountMsg(nil, reply, response)
   979  	}
   980  	s.sendJetStreamAPIAuditAdvisory(ci, acc, subject, request, response)
   981  }
   982  
   983  func (s *Server) sendAPIErrResponse(ci *ClientInfo, acc *Account, subject, reply, request, response string) {
   984  	acc.trackAPIErr()
   985  	if reply != _EMPTY_ {
   986  		s.sendInternalAccountMsg(nil, reply, response)
   987  	}
   988  	s.sendJetStreamAPIAuditAdvisory(ci, acc, subject, request, response)
   989  }
   990  
   991  const errRespDelay = 500 * time.Millisecond
   992  
   993  func (s *Server) sendDelayedAPIErrResponse(ci *ClientInfo, acc *Account, subject, reply, request, response string, rg *raftGroup) {
   994  	js := s.getJetStream()
   995  	if js == nil {
   996  		return
   997  	}
   998  	var quitCh <-chan struct{}
   999  	js.mu.RLock()
  1000  	if rg != nil && rg.node != nil {
  1001  		quitCh = rg.node.QuitC()
  1002  	}
  1003  	js.mu.RUnlock()
  1004  
  1005  	s.startGoRoutine(func() {
  1006  		defer s.grWG.Done()
  1007  		select {
  1008  		case <-quitCh:
  1009  		case <-s.quitCh:
  1010  		case <-time.After(errRespDelay):
  1011  			acc.trackAPIErr()
  1012  			if reply != _EMPTY_ {
  1013  				s.sendInternalAccountMsg(nil, reply, response)
  1014  			}
  1015  			s.sendJetStreamAPIAuditAdvisory(ci, acc, subject, request, response)
  1016  		}
  1017  	})
  1018  }
  1019  
  1020  func (s *Server) getRequestInfo(c *client, raw []byte) (pci *ClientInfo, acc *Account, hdr, msg []byte, err error) {
  1021  	hdr, msg = c.msgParts(raw)
  1022  	var ci ClientInfo
  1023  
  1024  	if len(hdr) > 0 {
  1025  		if err := json.Unmarshal(getHeader(ClientInfoHdr, hdr), &ci); err != nil {
  1026  			return nil, nil, nil, nil, err
  1027  		}
  1028  	}
  1029  
  1030  	if ci.Service != _EMPTY_ {
  1031  		acc, _ = s.LookupAccount(ci.Service)
  1032  	} else if ci.Account != _EMPTY_ {
  1033  		acc, _ = s.LookupAccount(ci.Account)
  1034  	} else {
  1035  		// Direct $SYS access.
  1036  		acc = c.acc
  1037  		if acc == nil {
  1038  			acc = s.SystemAccount()
  1039  		}
  1040  	}
  1041  	if acc == nil {
  1042  		return nil, nil, nil, nil, ErrMissingAccount
  1043  	}
  1044  	return &ci, acc, hdr, msg, nil
  1045  }
  1046  
  1047  func (a *Account) trackAPI() {
  1048  	a.mu.RLock()
  1049  	jsa := a.js
  1050  	a.mu.RUnlock()
  1051  	if jsa != nil {
  1052  		jsa.usageMu.Lock()
  1053  		jsa.usageApi++
  1054  		jsa.apiTotal++
  1055  		jsa.sendClusterUsageUpdate()
  1056  		atomic.AddInt64(&jsa.js.apiTotal, 1)
  1057  		jsa.usageMu.Unlock()
  1058  	}
  1059  }
  1060  
  1061  func (a *Account) trackAPIErr() {
  1062  	a.mu.RLock()
  1063  	jsa := a.js
  1064  	a.mu.RUnlock()
  1065  	if jsa != nil {
  1066  		jsa.usageMu.Lock()
  1067  		jsa.usageApi++
  1068  		jsa.apiTotal++
  1069  		jsa.usageErr++
  1070  		jsa.apiErrors++
  1071  		jsa.sendClusterUsageUpdate()
  1072  		atomic.AddInt64(&jsa.js.apiTotal, 1)
  1073  		atomic.AddInt64(&jsa.js.apiErrors, 1)
  1074  		jsa.usageMu.Unlock()
  1075  	}
  1076  }
  1077  
  1078  const badAPIRequestT = "Malformed JetStream API Request: %q"
  1079  
  1080  // Helper function to check on JetStream being enabled but also on status of leafnodes
  1081  // If the local account is not enabled but does have leafnode connectivity we will not
  1082  // want to error immediately and let the other side decide.
  1083  func (a *Account) checkJetStream() (enabled, shouldError bool) {
  1084  	a.mu.RLock()
  1085  	defer a.mu.RUnlock()
  1086  	return a.js != nil, a.nleafs+a.nrleafs == 0
  1087  }
  1088  
  1089  // Request for current usage and limits for this account.
  1090  func (s *Server) jsAccountInfoRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1091  	if c == nil || !s.JetStreamEnabled() {
  1092  		return
  1093  	}
  1094  
  1095  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1096  	if err != nil {
  1097  		s.Warnf(badAPIRequestT, msg)
  1098  		return
  1099  	}
  1100  
  1101  	var resp = JSApiAccountInfoResponse{ApiResponse: ApiResponse{Type: JSApiAccountInfoResponseType}}
  1102  
  1103  	// Determine if we should proceed here when we are in clustered mode.
  1104  	if s.JetStreamIsClustered() {
  1105  		js, cc := s.getJetStreamCluster()
  1106  		if js == nil || cc == nil {
  1107  			return
  1108  		}
  1109  		if js.isLeaderless() {
  1110  			resp.Error = NewJSClusterNotAvailError()
  1111  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1112  			return
  1113  		}
  1114  		// Make sure we are meta leader.
  1115  		if !s.JetStreamIsLeader() {
  1116  			return
  1117  		}
  1118  	}
  1119  
  1120  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1121  		if !doErr {
  1122  			return
  1123  		}
  1124  		resp.Error = NewJSNotEnabledForAccountError()
  1125  	} else {
  1126  		stats := acc.JetStreamUsage()
  1127  		resp.JetStreamAccountStats = &stats
  1128  	}
  1129  	b, err := json.Marshal(resp)
  1130  	if err != nil {
  1131  		return
  1132  	}
  1133  
  1134  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), string(b))
  1135  }
  1136  
  1137  // Helpers for token extraction.
  1138  func templateNameFromSubject(subject string) string {
  1139  	return tokenAt(subject, 6)
  1140  }
  1141  
  1142  func streamNameFromSubject(subject string) string {
  1143  	return tokenAt(subject, 5)
  1144  }
  1145  
  1146  func consumerNameFromSubject(subject string) string {
  1147  	return tokenAt(subject, 6)
  1148  }
  1149  
  1150  // Request to create a new template.
  1151  func (s *Server) jsTemplateCreateRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1152  	if c == nil {
  1153  		return
  1154  	}
  1155  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1156  	if err != nil {
  1157  		s.Warnf(badAPIRequestT, msg)
  1158  		return
  1159  	}
  1160  
  1161  	var resp = JSApiStreamTemplateCreateResponse{ApiResponse: ApiResponse{Type: JSApiStreamTemplateCreateResponseType}}
  1162  	if !acc.JetStreamEnabled() {
  1163  		resp.Error = NewJSNotEnabledForAccountError()
  1164  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1165  		return
  1166  	}
  1167  
  1168  	// Not supported for now.
  1169  	if s.JetStreamIsClustered() {
  1170  		resp.Error = NewJSClusterUnSupportFeatureError()
  1171  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1172  		return
  1173  	}
  1174  
  1175  	var cfg StreamTemplateConfig
  1176  	if err := json.Unmarshal(msg, &cfg); err != nil {
  1177  		resp.Error = NewJSInvalidJSONError()
  1178  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1179  		return
  1180  	}
  1181  	templateName := templateNameFromSubject(subject)
  1182  	if templateName != cfg.Name {
  1183  		resp.Error = NewJSTemplateNameNotMatchSubjectError()
  1184  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1185  		return
  1186  	}
  1187  
  1188  	t, err := acc.addStreamTemplate(&cfg)
  1189  	if err != nil {
  1190  		resp.Error = NewJSStreamTemplateCreateError(err, Unless(err))
  1191  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1192  		return
  1193  	}
  1194  	t.mu.Lock()
  1195  	tcfg := t.StreamTemplateConfig.deepCopy()
  1196  	streams := t.streams
  1197  	if streams == nil {
  1198  		streams = []string{}
  1199  	}
  1200  	t.mu.Unlock()
  1201  	resp.StreamTemplateInfo = &StreamTemplateInfo{Config: tcfg, Streams: streams}
  1202  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1203  }
  1204  
  1205  // Request for the list of all template names.
  1206  func (s *Server) jsTemplateNamesRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1207  	if c == nil {
  1208  		return
  1209  	}
  1210  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1211  	if err != nil {
  1212  		s.Warnf(badAPIRequestT, msg)
  1213  		return
  1214  	}
  1215  
  1216  	var resp = JSApiStreamTemplateNamesResponse{ApiResponse: ApiResponse{Type: JSApiStreamTemplateNamesResponseType}}
  1217  	if !acc.JetStreamEnabled() {
  1218  		resp.Error = NewJSNotEnabledForAccountError()
  1219  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1220  		return
  1221  	}
  1222  
  1223  	// Not supported for now.
  1224  	if s.JetStreamIsClustered() {
  1225  		resp.Error = NewJSClusterUnSupportFeatureError()
  1226  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1227  		return
  1228  	}
  1229  
  1230  	var offset int
  1231  	if !isEmptyRequest(msg) {
  1232  		var req JSApiStreamTemplatesRequest
  1233  		if err := json.Unmarshal(msg, &req); err != nil {
  1234  			resp.Error = NewJSInvalidJSONError()
  1235  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1236  			return
  1237  		}
  1238  		offset = req.Offset
  1239  	}
  1240  
  1241  	ts := acc.templates()
  1242  	sort.Slice(ts, func(i, j int) bool {
  1243  		return strings.Compare(ts[i].StreamTemplateConfig.Name, ts[j].StreamTemplateConfig.Name) < 0
  1244  	})
  1245  
  1246  	tcnt := len(ts)
  1247  	if offset > tcnt {
  1248  		offset = tcnt
  1249  	}
  1250  
  1251  	for _, t := range ts[offset:] {
  1252  		t.mu.Lock()
  1253  		name := t.Name
  1254  		t.mu.Unlock()
  1255  		resp.Templates = append(resp.Templates, name)
  1256  		if len(resp.Templates) >= JSApiNamesLimit {
  1257  			break
  1258  		}
  1259  	}
  1260  	resp.Total = tcnt
  1261  	resp.Limit = JSApiNamesLimit
  1262  	resp.Offset = offset
  1263  	if resp.Templates == nil {
  1264  		resp.Templates = []string{}
  1265  	}
  1266  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1267  }
  1268  
  1269  // Request for information about a stream template.
  1270  func (s *Server) jsTemplateInfoRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1271  	if c == nil {
  1272  		return
  1273  	}
  1274  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1275  	if err != nil {
  1276  		s.Warnf(badAPIRequestT, msg)
  1277  		return
  1278  	}
  1279  
  1280  	var resp = JSApiStreamTemplateInfoResponse{ApiResponse: ApiResponse{Type: JSApiStreamTemplateInfoResponseType}}
  1281  	if !acc.JetStreamEnabled() {
  1282  		resp.Error = NewJSNotEnabledForAccountError()
  1283  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1284  		return
  1285  	}
  1286  	if !isEmptyRequest(msg) {
  1287  		resp.Error = NewJSNotEmptyRequestError()
  1288  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1289  		return
  1290  	}
  1291  	name := templateNameFromSubject(subject)
  1292  	t, err := acc.lookupStreamTemplate(name)
  1293  	if err != nil {
  1294  		resp.Error = NewJSStreamTemplateNotFoundError()
  1295  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1296  		return
  1297  	}
  1298  	t.mu.Lock()
  1299  	cfg := t.StreamTemplateConfig.deepCopy()
  1300  	streams := t.streams
  1301  	if streams == nil {
  1302  		streams = []string{}
  1303  	}
  1304  	t.mu.Unlock()
  1305  
  1306  	resp.StreamTemplateInfo = &StreamTemplateInfo{Config: cfg, Streams: streams}
  1307  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1308  }
  1309  
  1310  // Request to delete a stream template.
  1311  func (s *Server) jsTemplateDeleteRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1312  	if c == nil {
  1313  		return
  1314  	}
  1315  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1316  	if err != nil {
  1317  		s.Warnf(badAPIRequestT, msg)
  1318  		return
  1319  	}
  1320  
  1321  	var resp = JSApiStreamTemplateDeleteResponse{ApiResponse: ApiResponse{Type: JSApiStreamTemplateDeleteResponseType}}
  1322  	if !acc.JetStreamEnabled() {
  1323  		resp.Error = NewJSNotEnabledForAccountError()
  1324  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1325  		return
  1326  	}
  1327  	if !isEmptyRequest(msg) {
  1328  		resp.Error = NewJSNotEmptyRequestError()
  1329  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1330  		return
  1331  	}
  1332  	name := templateNameFromSubject(subject)
  1333  	err = acc.deleteStreamTemplate(name)
  1334  	if err != nil {
  1335  		resp.Error = NewJSStreamTemplateDeleteError(err, Unless(err))
  1336  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1337  		return
  1338  	}
  1339  	resp.Success = true
  1340  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1341  }
  1342  
  1343  func (s *Server) jsonResponse(v interface{}) string {
  1344  	b, err := json.Marshal(v)
  1345  	if err != nil {
  1346  		s.Warnf("Problem marshaling JSON for JetStream API:", err)
  1347  		return ""
  1348  	}
  1349  	return string(b)
  1350  }
  1351  
  1352  // Read lock must be held
  1353  func (jsa *jsAccount) tieredReservation(tier string, cfg *StreamConfig) int64 {
  1354  	reservation := int64(0)
  1355  	if tier == _EMPTY_ {
  1356  		for _, sa := range jsa.streams {
  1357  			if sa.cfg.MaxBytes > 0 {
  1358  				if sa.cfg.Storage == cfg.Storage && sa.cfg.Name != cfg.Name {
  1359  					reservation += (int64(sa.cfg.Replicas) * sa.cfg.MaxBytes)
  1360  				}
  1361  			}
  1362  		}
  1363  	} else {
  1364  		for _, sa := range jsa.streams {
  1365  			if sa.cfg.Replicas == cfg.Replicas {
  1366  				if sa.cfg.MaxBytes > 0 {
  1367  					if isSameTier(&sa.cfg, cfg) && sa.cfg.Name != cfg.Name {
  1368  						reservation += (int64(sa.cfg.Replicas) * sa.cfg.MaxBytes)
  1369  					}
  1370  				}
  1371  			}
  1372  		}
  1373  	}
  1374  	return reservation
  1375  }
  1376  
  1377  // Request to create a stream.
  1378  func (s *Server) jsStreamCreateRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1379  	if c == nil || !s.JetStreamEnabled() {
  1380  		return
  1381  	}
  1382  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1383  	if err != nil {
  1384  		s.Warnf(badAPIRequestT, msg)
  1385  		return
  1386  	}
  1387  
  1388  	var resp = JSApiStreamCreateResponse{ApiResponse: ApiResponse{Type: JSApiStreamCreateResponseType}}
  1389  
  1390  	// Determine if we should proceed here when we are in clustered mode.
  1391  	if s.JetStreamIsClustered() {
  1392  		js, cc := s.getJetStreamCluster()
  1393  		if js == nil || cc == nil {
  1394  			return
  1395  		}
  1396  		if js.isLeaderless() {
  1397  			resp.Error = NewJSClusterNotAvailError()
  1398  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1399  			return
  1400  		}
  1401  		// Make sure we are meta leader.
  1402  		if !s.JetStreamIsLeader() {
  1403  			return
  1404  		}
  1405  	}
  1406  
  1407  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1408  		if doErr {
  1409  			resp.Error = NewJSNotEnabledForAccountError()
  1410  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1411  		}
  1412  		return
  1413  	}
  1414  
  1415  	var cfg StreamConfig
  1416  	if err := json.Unmarshal(msg, &cfg); err != nil {
  1417  		resp.Error = NewJSInvalidJSONError()
  1418  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1419  		return
  1420  	}
  1421  
  1422  	streamName := streamNameFromSubject(subject)
  1423  	if streamName != cfg.Name {
  1424  		resp.Error = NewJSStreamMismatchError()
  1425  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1426  		return
  1427  	}
  1428  
  1429  	// Check for path like separators in the name.
  1430  	if strings.ContainsAny(streamName, `\/`) {
  1431  		resp.Error = NewJSStreamNameContainsPathSeparatorsError()
  1432  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1433  		return
  1434  	}
  1435  
  1436  	// Can't create a stream with a sealed state.
  1437  	if cfg.Sealed {
  1438  		resp.Error = NewJSStreamInvalidConfigError(fmt.Errorf("stream configuration for create can not be sealed"))
  1439  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1440  		return
  1441  	}
  1442  
  1443  	// If we are told to do mirror direct but are not mirroring, error.
  1444  	if cfg.MirrorDirect && cfg.Mirror == nil {
  1445  		resp.Error = NewJSStreamInvalidConfigError(fmt.Errorf("stream has no mirror but does have mirror direct"))
  1446  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1447  		return
  1448  	}
  1449  
  1450  	// Hand off to cluster for processing.
  1451  	if s.JetStreamIsClustered() {
  1452  		s.jsClusteredStreamRequest(ci, acc, subject, reply, rmsg, &cfg)
  1453  		return
  1454  	}
  1455  
  1456  	if err := acc.jsNonClusteredStreamLimitsCheck(&cfg); err != nil {
  1457  		resp.Error = err
  1458  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1459  		return
  1460  	}
  1461  
  1462  	mset, err := acc.addStream(&cfg)
  1463  	if err != nil {
  1464  		if IsNatsErr(err, JSStreamStoreFailedF) {
  1465  			s.Warnf("Stream create failed for '%s > %s': %v", acc, streamName, err)
  1466  			err = errStreamStoreFailed
  1467  		}
  1468  		resp.Error = NewJSStreamCreateError(err, Unless(err))
  1469  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1470  		return
  1471  	}
  1472  	resp.StreamInfo = &StreamInfo{
  1473  		Created:   mset.createdTime(),
  1474  		State:     mset.state(),
  1475  		Config:    mset.config(),
  1476  		TimeStamp: time.Now().UTC(),
  1477  		Mirror:    mset.mirrorInfo(),
  1478  		Sources:   mset.sourcesInfo(),
  1479  	}
  1480  	resp.DidCreate = true
  1481  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1482  }
  1483  
  1484  // Request to update a stream.
  1485  func (s *Server) jsStreamUpdateRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1486  	if c == nil || !s.JetStreamEnabled() {
  1487  		return
  1488  	}
  1489  
  1490  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1491  	if err != nil {
  1492  		s.Warnf(badAPIRequestT, msg)
  1493  		return
  1494  	}
  1495  
  1496  	var resp = JSApiStreamUpdateResponse{ApiResponse: ApiResponse{Type: JSApiStreamUpdateResponseType}}
  1497  
  1498  	// Determine if we should proceed here when we are in clustered mode.
  1499  	if s.JetStreamIsClustered() {
  1500  		js, cc := s.getJetStreamCluster()
  1501  		if js == nil || cc == nil {
  1502  			return
  1503  		}
  1504  		if js.isLeaderless() {
  1505  			resp.Error = NewJSClusterNotAvailError()
  1506  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1507  			return
  1508  		}
  1509  		// Make sure we are meta leader.
  1510  		if !s.JetStreamIsLeader() {
  1511  			return
  1512  		}
  1513  	}
  1514  
  1515  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1516  		if doErr {
  1517  			resp.Error = NewJSNotEnabledForAccountError()
  1518  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1519  		}
  1520  		return
  1521  	}
  1522  	var ncfg StreamConfig
  1523  	if err := json.Unmarshal(msg, &ncfg); err != nil {
  1524  		resp.Error = NewJSInvalidJSONError()
  1525  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1526  		return
  1527  	}
  1528  
  1529  	cfg, apiErr := s.checkStreamCfg(&ncfg, acc)
  1530  	if apiErr != nil {
  1531  		resp.Error = apiErr
  1532  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1533  		return
  1534  	}
  1535  
  1536  	streamName := streamNameFromSubject(subject)
  1537  	if streamName != cfg.Name {
  1538  		resp.Error = NewJSStreamMismatchError()
  1539  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1540  		return
  1541  	}
  1542  
  1543  	// Handle clustered version here.
  1544  	if s.JetStreamIsClustered() {
  1545  		// Always do in separate Go routine.
  1546  		go s.jsClusteredStreamUpdateRequest(ci, acc, subject, reply, copyBytes(rmsg), &cfg, nil)
  1547  		return
  1548  	}
  1549  
  1550  	mset, err := acc.lookupStream(streamName)
  1551  	if err != nil {
  1552  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  1553  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1554  		return
  1555  	}
  1556  
  1557  	if err := mset.update(&cfg); err != nil {
  1558  		resp.Error = NewJSStreamUpdateError(err, Unless(err))
  1559  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1560  		return
  1561  	}
  1562  
  1563  	resp.StreamInfo = &StreamInfo{
  1564  		Created:   mset.createdTime(),
  1565  		State:     mset.state(),
  1566  		Config:    mset.config(),
  1567  		Domain:    s.getOpts().JetStreamDomain,
  1568  		Mirror:    mset.mirrorInfo(),
  1569  		Sources:   mset.sourcesInfo(),
  1570  		TimeStamp: time.Now().UTC(),
  1571  	}
  1572  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1573  }
  1574  
  1575  // Request for the list of all stream names.
  1576  func (s *Server) jsStreamNamesRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1577  	if c == nil || !s.JetStreamEnabled() {
  1578  		return
  1579  	}
  1580  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1581  	if err != nil {
  1582  		s.Warnf(badAPIRequestT, msg)
  1583  		return
  1584  	}
  1585  
  1586  	var resp = JSApiStreamNamesResponse{ApiResponse: ApiResponse{Type: JSApiStreamNamesResponseType}}
  1587  
  1588  	// Determine if we should proceed here when we are in clustered mode.
  1589  	if s.JetStreamIsClustered() {
  1590  		js, cc := s.getJetStreamCluster()
  1591  		if js == nil || cc == nil {
  1592  			return
  1593  		}
  1594  		if js.isLeaderless() {
  1595  			resp.Error = NewJSClusterNotAvailError()
  1596  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1597  			return
  1598  		}
  1599  		// Make sure we are meta leader.
  1600  		if !s.JetStreamIsLeader() {
  1601  			return
  1602  		}
  1603  	}
  1604  
  1605  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1606  		if doErr {
  1607  			resp.Error = NewJSNotEnabledForAccountError()
  1608  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1609  		}
  1610  		return
  1611  	}
  1612  
  1613  	var offset int
  1614  	var filter string
  1615  
  1616  	if !isEmptyRequest(msg) {
  1617  		var req JSApiStreamNamesRequest
  1618  		if err := json.Unmarshal(msg, &req); err != nil {
  1619  			resp.Error = NewJSInvalidJSONError()
  1620  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1621  			return
  1622  		}
  1623  		offset = req.Offset
  1624  		if req.Subject != _EMPTY_ {
  1625  			filter = req.Subject
  1626  		}
  1627  	}
  1628  
  1629  	// TODO(dlc) - Maybe hold these results for large results that we expect to be paged.
  1630  	// TODO(dlc) - If this list is long maybe do this in a Go routine?
  1631  	var numStreams int
  1632  	if s.JetStreamIsClustered() {
  1633  		js, cc := s.getJetStreamCluster()
  1634  		if js == nil || cc == nil {
  1635  			// TODO(dlc) - Debug or Warn?
  1636  			return
  1637  		}
  1638  		js.mu.RLock()
  1639  		for stream, sa := range cc.streams[acc.Name] {
  1640  			if IsNatsErr(sa.err, JSClusterNotAssignedErr) {
  1641  				continue
  1642  			}
  1643  			if filter != _EMPTY_ {
  1644  				// These could not have subjects auto-filled in since they are raw and unprocessed.
  1645  				if len(sa.Config.Subjects) == 0 {
  1646  					if SubjectsCollide(filter, sa.Config.Name) {
  1647  						resp.Streams = append(resp.Streams, stream)
  1648  					}
  1649  				} else {
  1650  					for _, subj := range sa.Config.Subjects {
  1651  						if SubjectsCollide(filter, subj) {
  1652  							resp.Streams = append(resp.Streams, stream)
  1653  							break
  1654  						}
  1655  					}
  1656  				}
  1657  			} else {
  1658  				resp.Streams = append(resp.Streams, stream)
  1659  			}
  1660  		}
  1661  		js.mu.RUnlock()
  1662  		if len(resp.Streams) > 1 {
  1663  			sort.Slice(resp.Streams, func(i, j int) bool { return strings.Compare(resp.Streams[i], resp.Streams[j]) < 0 })
  1664  		}
  1665  		numStreams = len(resp.Streams)
  1666  		if offset > numStreams {
  1667  			offset = numStreams
  1668  		}
  1669  		if offset > 0 {
  1670  			resp.Streams = resp.Streams[offset:]
  1671  		}
  1672  		if len(resp.Streams) > JSApiNamesLimit {
  1673  			resp.Streams = resp.Streams[:JSApiNamesLimit]
  1674  		}
  1675  	} else {
  1676  		msets := acc.filteredStreams(filter)
  1677  		// Since we page results order matters.
  1678  		if len(msets) > 1 {
  1679  			sort.Slice(msets, func(i, j int) bool {
  1680  				return strings.Compare(msets[i].cfg.Name, msets[j].cfg.Name) < 0
  1681  			})
  1682  		}
  1683  
  1684  		numStreams = len(msets)
  1685  		if offset > numStreams {
  1686  			offset = numStreams
  1687  		}
  1688  
  1689  		for _, mset := range msets[offset:] {
  1690  			resp.Streams = append(resp.Streams, mset.cfg.Name)
  1691  			if len(resp.Streams) >= JSApiNamesLimit {
  1692  				break
  1693  			}
  1694  		}
  1695  	}
  1696  	resp.Total = numStreams
  1697  	resp.Limit = JSApiNamesLimit
  1698  	resp.Offset = offset
  1699  
  1700  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1701  }
  1702  
  1703  // Request for the list of all detailed stream info.
  1704  // TODO(dlc) - combine with above long term
  1705  func (s *Server) jsStreamListRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  1706  	if c == nil || !s.JetStreamEnabled() {
  1707  		return
  1708  	}
  1709  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  1710  	if err != nil {
  1711  		s.Warnf(badAPIRequestT, msg)
  1712  		return
  1713  	}
  1714  
  1715  	var resp = JSApiStreamListResponse{
  1716  		ApiResponse: ApiResponse{Type: JSApiStreamListResponseType},
  1717  		Streams:     []*StreamInfo{},
  1718  	}
  1719  
  1720  	// Determine if we should proceed here when we are in clustered mode.
  1721  	if s.JetStreamIsClustered() {
  1722  		js, cc := s.getJetStreamCluster()
  1723  		if js == nil || cc == nil {
  1724  			return
  1725  		}
  1726  		if js.isLeaderless() {
  1727  			resp.Error = NewJSClusterNotAvailError()
  1728  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1729  			return
  1730  		}
  1731  		// Make sure we are meta leader.
  1732  		if !s.JetStreamIsLeader() {
  1733  			return
  1734  		}
  1735  	}
  1736  
  1737  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1738  		if doErr {
  1739  			resp.Error = NewJSNotEnabledForAccountError()
  1740  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1741  		}
  1742  		return
  1743  	}
  1744  
  1745  	var offset int
  1746  	var filter string
  1747  
  1748  	if !isEmptyRequest(msg) {
  1749  		var req JSApiStreamListRequest
  1750  		if err := json.Unmarshal(msg, &req); err != nil {
  1751  			resp.Error = NewJSInvalidJSONError()
  1752  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1753  			return
  1754  		}
  1755  		offset = req.Offset
  1756  		if req.Subject != _EMPTY_ {
  1757  			filter = req.Subject
  1758  		}
  1759  	}
  1760  
  1761  	// Clustered mode will invoke a scatter and gather.
  1762  	if s.JetStreamIsClustered() {
  1763  		// Need to copy these off before sending.. don't move this inside startGoRoutine!!!
  1764  		msg = copyBytes(msg)
  1765  		s.startGoRoutine(func() { s.jsClusteredStreamListRequest(acc, ci, filter, offset, subject, reply, msg) })
  1766  		return
  1767  	}
  1768  
  1769  	// TODO(dlc) - Maybe hold these results for large results that we expect to be paged.
  1770  	// TODO(dlc) - If this list is long maybe do this in a Go routine?
  1771  	var msets []*stream
  1772  	if filter == _EMPTY_ {
  1773  		msets = acc.streams()
  1774  	} else {
  1775  		msets = acc.filteredStreams(filter)
  1776  	}
  1777  
  1778  	sort.Slice(msets, func(i, j int) bool {
  1779  		return strings.Compare(msets[i].cfg.Name, msets[j].cfg.Name) < 0
  1780  	})
  1781  
  1782  	scnt := len(msets)
  1783  	if offset > scnt {
  1784  		offset = scnt
  1785  	}
  1786  
  1787  	for _, mset := range msets[offset:] {
  1788  		config := mset.config()
  1789  		resp.Streams = append(resp.Streams, &StreamInfo{
  1790  			Created:   mset.createdTime(),
  1791  			State:     mset.state(),
  1792  			Config:    config,
  1793  			Domain:    s.getOpts().JetStreamDomain,
  1794  			Mirror:    mset.mirrorInfo(),
  1795  			Sources:   mset.sourcesInfo(),
  1796  			TimeStamp: time.Now().UTC(),
  1797  		})
  1798  		if len(resp.Streams) >= JSApiListLimit {
  1799  			break
  1800  		}
  1801  	}
  1802  	resp.Total = scnt
  1803  	resp.Limit = JSApiListLimit
  1804  	resp.Offset = offset
  1805  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  1806  }
  1807  
  1808  // Request for information about a stream.
  1809  func (s *Server) jsStreamInfoRequest(sub *subscription, c *client, a *Account, subject, reply string, rmsg []byte) {
  1810  	if c == nil || !s.JetStreamEnabled() {
  1811  		return
  1812  	}
  1813  	ci, acc, hdr, msg, err := s.getRequestInfo(c, rmsg)
  1814  	if err != nil {
  1815  		s.Warnf(badAPIRequestT, msg)
  1816  		return
  1817  	}
  1818  
  1819  	streamName := streamNameFromSubject(subject)
  1820  
  1821  	var resp = JSApiStreamInfoResponse{ApiResponse: ApiResponse{Type: JSApiStreamInfoResponseType}}
  1822  
  1823  	// If someone creates a duplicate stream that is identical we will get this request forwarded to us.
  1824  	// Make sure the response type is for a create call.
  1825  	if rt := getHeader(JSResponseType, hdr); len(rt) > 0 && string(rt) == jsCreateResponse {
  1826  		resp.ApiResponse.Type = JSApiStreamCreateResponseType
  1827  	}
  1828  
  1829  	var clusterWideConsCount int
  1830  
  1831  	js, cc := s.getJetStreamCluster()
  1832  	if js == nil {
  1833  		return
  1834  	}
  1835  	// If we are in clustered mode we need to be the stream leader to proceed.
  1836  	if cc != nil {
  1837  		// Check to make sure the stream is assigned.
  1838  		js.mu.RLock()
  1839  		isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, streamName)
  1840  		var offline bool
  1841  		if sa != nil {
  1842  			clusterWideConsCount = len(sa.consumers)
  1843  			offline = s.allPeersOffline(sa.Group)
  1844  		}
  1845  		js.mu.RUnlock()
  1846  
  1847  		if isLeader && sa == nil {
  1848  			// We can't find the stream, so mimic what would be the errors below.
  1849  			if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1850  				if doErr {
  1851  					resp.Error = NewJSNotEnabledForAccountError()
  1852  					s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1853  				}
  1854  				return
  1855  			}
  1856  			// No stream present.
  1857  			resp.Error = NewJSStreamNotFoundError()
  1858  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1859  			return
  1860  		} else if sa == nil {
  1861  			if js.isLeaderless() {
  1862  				resp.Error = NewJSClusterNotAvailError()
  1863  				// Delaying an error response gives the leader a chance to respond before us
  1864  				s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), nil)
  1865  			}
  1866  			return
  1867  		} else if isLeader && offline {
  1868  			resp.Error = NewJSStreamOfflineError()
  1869  			s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), nil)
  1870  			return
  1871  		}
  1872  
  1873  		// Check to see if we are a member of the group and if the group has no leader.
  1874  		isLeaderless := js.isGroupLeaderless(sa.Group)
  1875  
  1876  		// We have the stream assigned and a leader, so only the stream leader should answer.
  1877  		if !acc.JetStreamIsStreamLeader(streamName) && !isLeaderless {
  1878  			if js.isLeaderless() {
  1879  				resp.Error = NewJSClusterNotAvailError()
  1880  				// Delaying an error response gives the leader a chance to respond before us
  1881  				s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), sa.Group)
  1882  				return
  1883  			}
  1884  
  1885  			// We may be in process of electing a leader, but if this is a scale up from 1 we will still be the state leader
  1886  			// while the new members work through the election and catchup process.
  1887  			// Double check for that instead of exiting here and being silent. e.g. nats stream update test --replicas=3
  1888  			js.mu.RLock()
  1889  			rg := sa.Group
  1890  			var ourID string
  1891  			if cc.meta != nil {
  1892  				ourID = cc.meta.ID()
  1893  			}
  1894  			// We have seen cases where rg or rg.node is nil at this point,
  1895  			// so check explicitly on those conditions and bail if that is
  1896  			// the case.
  1897  			bail := rg == nil || rg.node == nil || !rg.isMember(ourID)
  1898  			if !bail {
  1899  				// We know we are a member here, if this group is new and we are preferred allow us to answer.
  1900  				bail = rg.Preferred != ourID || time.Since(rg.node.Created()) > lostQuorumIntervalDefault
  1901  			}
  1902  			js.mu.RUnlock()
  1903  			if bail {
  1904  				return
  1905  			}
  1906  		}
  1907  	}
  1908  
  1909  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  1910  		if doErr {
  1911  			resp.Error = NewJSNotEnabledForAccountError()
  1912  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1913  		}
  1914  		return
  1915  	}
  1916  
  1917  	var details bool
  1918  	var subjects string
  1919  	var offset int
  1920  	if !isEmptyRequest(msg) {
  1921  		var req JSApiStreamInfoRequest
  1922  		if err := json.Unmarshal(msg, &req); err != nil {
  1923  			resp.Error = NewJSInvalidJSONError()
  1924  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1925  			return
  1926  		}
  1927  		details, subjects = req.DeletedDetails, req.SubjectsFilter
  1928  		offset = req.Offset
  1929  	}
  1930  
  1931  	mset, err := acc.lookupStream(streamName)
  1932  	// Error is not to be expected at this point, but could happen if same stream trying to be created.
  1933  	if err != nil {
  1934  		if cc != nil {
  1935  			// This could be inflight, pause for a short bit and try again.
  1936  			// This will not be inline, so ok.
  1937  			time.Sleep(10 * time.Millisecond)
  1938  			mset, err = acc.lookupStream(streamName)
  1939  		}
  1940  		// Check again.
  1941  		if err != nil {
  1942  			resp.Error = NewJSStreamNotFoundError(Unless(err))
  1943  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  1944  			return
  1945  		}
  1946  	}
  1947  	config := mset.config()
  1948  
  1949  	resp.StreamInfo = &StreamInfo{
  1950  		Created:    mset.createdTime(),
  1951  		State:      mset.stateWithDetail(details),
  1952  		Config:     config,
  1953  		Domain:     s.getOpts().JetStreamDomain,
  1954  		Cluster:    js.clusterInfo(mset.raftGroup()),
  1955  		Mirror:     mset.mirrorInfo(),
  1956  		Sources:    mset.sourcesInfo(),
  1957  		Alternates: js.streamAlternates(ci, config.Name),
  1958  		TimeStamp:  time.Now().UTC(),
  1959  	}
  1960  	if clusterWideConsCount > 0 {
  1961  		resp.StreamInfo.State.Consumers = clusterWideConsCount
  1962  	}
  1963  
  1964  	// Check if they have asked for subject details.
  1965  	if subjects != _EMPTY_ {
  1966  		st := mset.store.SubjectsTotals(subjects)
  1967  		if lst := len(st); lst > 0 {
  1968  			// Common for both cases.
  1969  			resp.Offset = offset
  1970  			resp.Limit = JSMaxSubjectDetails
  1971  			resp.Total = lst
  1972  
  1973  			if offset == 0 && lst <= JSMaxSubjectDetails {
  1974  				resp.StreamInfo.State.Subjects = st
  1975  			} else {
  1976  				// Here we have to filter list due to offset or maximum constraints.
  1977  				subjs := make([]string, 0, len(st))
  1978  				for subj := range st {
  1979  					subjs = append(subjs, subj)
  1980  				}
  1981  				// Sort it
  1982  				sort.Strings(subjs)
  1983  
  1984  				if offset > len(subjs) {
  1985  					offset = len(subjs)
  1986  				}
  1987  
  1988  				end := offset + JSMaxSubjectDetails
  1989  				if end > len(subjs) {
  1990  					end = len(subjs)
  1991  				}
  1992  				actualSize := end - offset
  1993  				var sd map[string]uint64
  1994  
  1995  				if actualSize > 0 {
  1996  					sd = make(map[string]uint64, actualSize)
  1997  					for _, ss := range subjs[offset:end] {
  1998  						sd[ss] = st[ss]
  1999  					}
  2000  				}
  2001  				resp.StreamInfo.State.Subjects = sd
  2002  			}
  2003  		}
  2004  	}
  2005  	// Check for out of band catchups.
  2006  	if mset.hasCatchupPeers() {
  2007  		mset.checkClusterInfo(resp.StreamInfo.Cluster)
  2008  	}
  2009  
  2010  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2011  }
  2012  
  2013  // Request to have a stream leader stepdown.
  2014  func (s *Server) jsStreamLeaderStepDownRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2015  	if c == nil || !s.JetStreamEnabled() {
  2016  		return
  2017  	}
  2018  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2019  	if err != nil {
  2020  		s.Warnf(badAPIRequestT, msg)
  2021  		return
  2022  	}
  2023  
  2024  	// Have extra token for this one.
  2025  	name := tokenAt(subject, 6)
  2026  
  2027  	var resp = JSApiStreamLeaderStepDownResponse{ApiResponse: ApiResponse{Type: JSApiStreamLeaderStepDownResponseType}}
  2028  
  2029  	// If we are not in clustered mode this is a failed request.
  2030  	if !s.JetStreamIsClustered() {
  2031  		resp.Error = NewJSClusterRequiredError()
  2032  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2033  		return
  2034  	}
  2035  
  2036  	// If we are here we are clustered. See if we are the stream leader in order to proceed.
  2037  	js, cc := s.getJetStreamCluster()
  2038  	if js == nil || cc == nil {
  2039  		return
  2040  	}
  2041  	if js.isLeaderless() {
  2042  		resp.Error = NewJSClusterNotAvailError()
  2043  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2044  		return
  2045  	}
  2046  
  2047  	js.mu.RLock()
  2048  	isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, name)
  2049  	js.mu.RUnlock()
  2050  
  2051  	if isLeader && sa == nil {
  2052  		resp.Error = NewJSStreamNotFoundError()
  2053  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2054  		return
  2055  	} else if sa == nil {
  2056  		return
  2057  	}
  2058  
  2059  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2060  		if doErr {
  2061  			resp.Error = NewJSNotEnabledForAccountError()
  2062  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2063  		}
  2064  		return
  2065  	}
  2066  	if !isEmptyRequest(msg) {
  2067  		resp.Error = NewJSBadRequestError()
  2068  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2069  		return
  2070  	}
  2071  
  2072  	// Check to see if we are a member of the group and if the group has no leader.
  2073  	if js.isGroupLeaderless(sa.Group) {
  2074  		resp.Error = NewJSClusterNotAvailError()
  2075  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2076  		return
  2077  	}
  2078  
  2079  	// We have the stream assigned and a leader, so only the stream leader should answer.
  2080  	if !acc.JetStreamIsStreamLeader(name) {
  2081  		return
  2082  	}
  2083  
  2084  	mset, err := acc.lookupStream(name)
  2085  	if err != nil {
  2086  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  2087  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2088  		return
  2089  	}
  2090  
  2091  	if mset == nil {
  2092  		resp.Success = true
  2093  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2094  		return
  2095  	}
  2096  
  2097  	// Call actual stepdown. Do this in a Go routine.
  2098  	go func() {
  2099  		if node := mset.raftNode(); node != nil {
  2100  			mset.setLeader(false)
  2101  			// TODO (mh) eventually make sure all go routines exited and all channels are cleared
  2102  			time.Sleep(250 * time.Millisecond)
  2103  			node.StepDown()
  2104  		}
  2105  
  2106  		resp.Success = true
  2107  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2108  	}()
  2109  }
  2110  
  2111  // Request to have a consumer leader stepdown.
  2112  func (s *Server) jsConsumerLeaderStepDownRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2113  	if c == nil || !s.JetStreamEnabled() {
  2114  		return
  2115  	}
  2116  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2117  	if err != nil {
  2118  		s.Warnf(badAPIRequestT, msg)
  2119  		return
  2120  	}
  2121  
  2122  	var resp = JSApiConsumerLeaderStepDownResponse{ApiResponse: ApiResponse{Type: JSApiConsumerLeaderStepDownResponseType}}
  2123  
  2124  	// If we are not in clustered mode this is a failed request.
  2125  	if !s.JetStreamIsClustered() {
  2126  		resp.Error = NewJSClusterRequiredError()
  2127  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2128  		return
  2129  	}
  2130  
  2131  	// If we are here we are clustered. See if we are the stream leader in order to proceed.
  2132  	js, cc := s.getJetStreamCluster()
  2133  	if js == nil || cc == nil {
  2134  		return
  2135  	}
  2136  	if js.isLeaderless() {
  2137  		resp.Error = NewJSClusterNotAvailError()
  2138  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2139  		return
  2140  	}
  2141  
  2142  	// Have extra token for this one.
  2143  	stream := tokenAt(subject, 6)
  2144  	consumer := tokenAt(subject, 7)
  2145  
  2146  	js.mu.RLock()
  2147  	isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, stream)
  2148  	js.mu.RUnlock()
  2149  
  2150  	if isLeader && sa == nil {
  2151  		resp.Error = NewJSStreamNotFoundError()
  2152  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2153  		return
  2154  	} else if sa == nil {
  2155  		return
  2156  	}
  2157  	var ca *consumerAssignment
  2158  	if sa.consumers != nil {
  2159  		ca = sa.consumers[consumer]
  2160  	}
  2161  	if ca == nil {
  2162  		resp.Error = NewJSConsumerNotFoundError()
  2163  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2164  		return
  2165  	}
  2166  	// Check to see if we are a member of the group and if the group has no leader.
  2167  	if js.isGroupLeaderless(ca.Group) {
  2168  		resp.Error = NewJSClusterNotAvailError()
  2169  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2170  		return
  2171  	}
  2172  
  2173  	if !acc.JetStreamIsConsumerLeader(stream, consumer) {
  2174  		return
  2175  	}
  2176  
  2177  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2178  		if doErr {
  2179  			resp.Error = NewJSNotEnabledForAccountError()
  2180  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2181  		}
  2182  		return
  2183  	}
  2184  	if !isEmptyRequest(msg) {
  2185  		resp.Error = NewJSBadRequestError()
  2186  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2187  		return
  2188  	}
  2189  
  2190  	mset, err := acc.lookupStream(stream)
  2191  	if err != nil {
  2192  		resp.Error = NewJSStreamNotFoundError()
  2193  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2194  		return
  2195  	}
  2196  	o := mset.lookupConsumer(consumer)
  2197  	if o == nil {
  2198  		resp.Error = NewJSConsumerNotFoundError()
  2199  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2200  		return
  2201  	}
  2202  
  2203  	n := o.raftNode()
  2204  	if n == nil {
  2205  		resp.Success = true
  2206  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2207  		return
  2208  	}
  2209  
  2210  	// Call actual stepdown. Do this in a Go routine.
  2211  	go func() {
  2212  		o.setLeader(false)
  2213  		// TODO (mh) eventually make sure all go routines exited and all channels are cleared
  2214  		time.Sleep(250 * time.Millisecond)
  2215  		n.StepDown()
  2216  
  2217  		resp.Success = true
  2218  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2219  	}()
  2220  }
  2221  
  2222  // Request to remove a peer from a clustered stream.
  2223  func (s *Server) jsStreamRemovePeerRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2224  	if c == nil || !s.JetStreamEnabled() {
  2225  		return
  2226  	}
  2227  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2228  	if err != nil {
  2229  		s.Warnf(badAPIRequestT, msg)
  2230  		return
  2231  	}
  2232  
  2233  	// Have extra token for this one.
  2234  	name := tokenAt(subject, 6)
  2235  
  2236  	var resp = JSApiStreamRemovePeerResponse{ApiResponse: ApiResponse{Type: JSApiStreamRemovePeerResponseType}}
  2237  
  2238  	// If we are not in clustered mode this is a failed request.
  2239  	if !s.JetStreamIsClustered() {
  2240  		resp.Error = NewJSClusterRequiredError()
  2241  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2242  		return
  2243  	}
  2244  
  2245  	// If we are here we are clustered. See if we are the stream leader in order to proceed.
  2246  	js, cc := s.getJetStreamCluster()
  2247  	if js == nil || cc == nil {
  2248  		return
  2249  	}
  2250  	if js.isLeaderless() {
  2251  		resp.Error = NewJSClusterNotAvailError()
  2252  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2253  		return
  2254  	}
  2255  
  2256  	js.mu.RLock()
  2257  	isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, name)
  2258  	js.mu.RUnlock()
  2259  
  2260  	// Make sure we are meta leader.
  2261  	if !isLeader {
  2262  		return
  2263  	}
  2264  
  2265  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2266  		if doErr {
  2267  			resp.Error = NewJSNotEnabledForAccountError()
  2268  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2269  		}
  2270  		return
  2271  	}
  2272  	if isEmptyRequest(msg) {
  2273  		resp.Error = NewJSBadRequestError()
  2274  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2275  		return
  2276  	}
  2277  
  2278  	var req JSApiStreamRemovePeerRequest
  2279  	if err := json.Unmarshal(msg, &req); err != nil {
  2280  		resp.Error = NewJSInvalidJSONError()
  2281  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2282  		return
  2283  	}
  2284  	if req.Peer == _EMPTY_ {
  2285  		resp.Error = NewJSBadRequestError()
  2286  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2287  		return
  2288  	}
  2289  
  2290  	if sa == nil {
  2291  		// No stream present.
  2292  		resp.Error = NewJSStreamNotFoundError()
  2293  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2294  		return
  2295  	}
  2296  
  2297  	// Check to see if we are a member of the group and if the group has no leader.
  2298  	// Peers here is a server name, convert to node name.
  2299  	nodeName := getHash(req.Peer)
  2300  
  2301  	js.mu.RLock()
  2302  	rg := sa.Group
  2303  	isMember := rg.isMember(nodeName)
  2304  	js.mu.RUnlock()
  2305  
  2306  	// Make sure we are a member.
  2307  	if !isMember {
  2308  		resp.Error = NewJSClusterPeerNotMemberError()
  2309  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2310  		return
  2311  	}
  2312  
  2313  	// If we are here we have a valid peer member set for removal.
  2314  	if !js.removePeerFromStream(sa, nodeName) {
  2315  		resp.Error = NewJSPeerRemapError()
  2316  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2317  		return
  2318  	}
  2319  
  2320  	resp.Success = true
  2321  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2322  }
  2323  
  2324  // Request to have the metaleader remove a peer from the system.
  2325  func (s *Server) jsLeaderServerRemoveRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2326  	if c == nil || !s.JetStreamEnabled() {
  2327  		return
  2328  	}
  2329  
  2330  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2331  	if err != nil {
  2332  		s.Warnf(badAPIRequestT, msg)
  2333  		return
  2334  	}
  2335  
  2336  	js, cc := s.getJetStreamCluster()
  2337  	if js == nil || cc == nil || cc.meta == nil {
  2338  		return
  2339  	}
  2340  
  2341  	// Extra checks here but only leader is listening.
  2342  	js.mu.RLock()
  2343  	isLeader := cc.isLeader()
  2344  	js.mu.RUnlock()
  2345  
  2346  	if !isLeader {
  2347  		return
  2348  	}
  2349  
  2350  	var resp = JSApiMetaServerRemoveResponse{ApiResponse: ApiResponse{Type: JSApiMetaServerRemoveResponseType}}
  2351  
  2352  	if isEmptyRequest(msg) {
  2353  		resp.Error = NewJSBadRequestError()
  2354  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2355  		return
  2356  	}
  2357  
  2358  	var req JSApiMetaServerRemoveRequest
  2359  	if err := json.Unmarshal(msg, &req); err != nil {
  2360  		resp.Error = NewJSInvalidJSONError()
  2361  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2362  		return
  2363  	}
  2364  
  2365  	var found string
  2366  	js.mu.RLock()
  2367  	for _, p := range cc.meta.Peers() {
  2368  		// If Peer is specified, it takes precedence
  2369  		if req.Peer != _EMPTY_ {
  2370  			if p.ID == req.Peer {
  2371  				found = req.Peer
  2372  				break
  2373  			}
  2374  			continue
  2375  		}
  2376  		si, ok := s.nodeToInfo.Load(p.ID)
  2377  		if ok && si.(nodeInfo).name == req.Server {
  2378  			found = p.ID
  2379  			break
  2380  		}
  2381  	}
  2382  	js.mu.RUnlock()
  2383  
  2384  	if found == _EMPTY_ {
  2385  		resp.Error = NewJSClusterServerNotMemberError()
  2386  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2387  		return
  2388  	}
  2389  
  2390  	// So we have a valid peer.
  2391  	js.mu.Lock()
  2392  	cc.meta.ProposeRemovePeer(found)
  2393  	js.mu.Unlock()
  2394  
  2395  	resp.Success = true
  2396  	s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2397  }
  2398  
  2399  func (s *Server) peerSetToNames(ps []string) []string {
  2400  	names := make([]string, len(ps))
  2401  	for i := 0; i < len(ps); i++ {
  2402  		if si, ok := s.nodeToInfo.Load(ps[i]); !ok {
  2403  			names[i] = ps[i]
  2404  		} else {
  2405  			names[i] = si.(nodeInfo).name
  2406  		}
  2407  	}
  2408  	return names
  2409  }
  2410  
  2411  // looks up the peer id for a given server name. Cluster and domain name are optional filter criteria
  2412  func (s *Server) nameToPeer(js *jetStream, serverName, clusterName, domainName string) string {
  2413  	js.mu.RLock()
  2414  	defer js.mu.RUnlock()
  2415  	if cc := js.cluster; cc != nil {
  2416  		for _, p := range cc.meta.Peers() {
  2417  			si, ok := s.nodeToInfo.Load(p.ID)
  2418  			if ok && si.(nodeInfo).name == serverName {
  2419  				if clusterName == _EMPTY_ || clusterName == si.(nodeInfo).cluster {
  2420  					if domainName == _EMPTY_ || domainName == si.(nodeInfo).domain {
  2421  						return p.ID
  2422  					}
  2423  				}
  2424  			}
  2425  		}
  2426  	}
  2427  	return _EMPTY_
  2428  }
  2429  
  2430  // Request to have the metaleader move a stream on a peer to another
  2431  func (s *Server) jsLeaderServerStreamMoveRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2432  	if c == nil || !s.JetStreamEnabled() {
  2433  		return
  2434  	}
  2435  
  2436  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2437  	if err != nil {
  2438  		s.Warnf(badAPIRequestT, msg)
  2439  		return
  2440  	}
  2441  
  2442  	js, cc := s.getJetStreamCluster()
  2443  	if js == nil || cc == nil || cc.meta == nil {
  2444  		return
  2445  	}
  2446  
  2447  	// Extra checks here but only leader is listening.
  2448  	js.mu.RLock()
  2449  	isLeader := cc.isLeader()
  2450  	js.mu.RUnlock()
  2451  
  2452  	if !isLeader {
  2453  		return
  2454  	}
  2455  
  2456  	accName := tokenAt(subject, 6)
  2457  	streamName := tokenAt(subject, 7)
  2458  
  2459  	var resp = JSApiStreamUpdateResponse{ApiResponse: ApiResponse{Type: JSApiStreamUpdateResponseType}}
  2460  
  2461  	var req JSApiMetaServerStreamMoveRequest
  2462  	if err := json.Unmarshal(msg, &req); err != nil {
  2463  		resp.Error = NewJSInvalidJSONError()
  2464  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2465  		return
  2466  	}
  2467  
  2468  	srcPeer := _EMPTY_
  2469  	if req.Server != _EMPTY_ {
  2470  		srcPeer = s.nameToPeer(js, req.Server, req.Cluster, req.Domain)
  2471  	}
  2472  
  2473  	targetAcc, ok := s.accounts.Load(accName)
  2474  	if !ok {
  2475  		resp.Error = NewJSNoAccountError()
  2476  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2477  		return
  2478  	}
  2479  
  2480  	var streamFound bool
  2481  	cfg := StreamConfig{}
  2482  	currPeers := []string{}
  2483  	currCluster := _EMPTY_
  2484  	js.mu.Lock()
  2485  	streams, ok := cc.streams[accName]
  2486  	if ok {
  2487  		sa, ok := streams[streamName]
  2488  		if ok {
  2489  			cfg = *sa.Config
  2490  			streamFound = true
  2491  			currPeers = sa.Group.Peers
  2492  			currCluster = sa.Group.Cluster
  2493  		}
  2494  	}
  2495  	js.mu.Unlock()
  2496  
  2497  	if !streamFound {
  2498  		resp.Error = NewJSStreamNotFoundError()
  2499  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2500  		return
  2501  	}
  2502  
  2503  	// if server was picked, make sure src peer exists and move it to first position.
  2504  	// removal will drop peers from the left
  2505  	if req.Server != _EMPTY_ {
  2506  		if srcPeer == _EMPTY_ {
  2507  			resp.Error = NewJSClusterServerNotMemberError()
  2508  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2509  			return
  2510  		}
  2511  		var peerFound bool
  2512  		for i := 0; i < len(currPeers); i++ {
  2513  			if currPeers[i] == srcPeer {
  2514  				copy(currPeers[1:], currPeers[:i])
  2515  				currPeers[0] = srcPeer
  2516  				peerFound = true
  2517  				break
  2518  			}
  2519  		}
  2520  		if !peerFound {
  2521  			resp.Error = NewJSClusterPeerNotMemberError()
  2522  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2523  			return
  2524  		}
  2525  	}
  2526  
  2527  	// make sure client is scoped to requested account
  2528  	ciNew := *(ci)
  2529  	ciNew.Account = accName
  2530  
  2531  	// backup placement such that peers can be looked up with modified tag list
  2532  	var origPlacement *Placement
  2533  	if cfg.Placement != nil {
  2534  		tmp := *cfg.Placement
  2535  		origPlacement = &tmp
  2536  	}
  2537  
  2538  	if len(req.Tags) > 0 {
  2539  		if cfg.Placement == nil {
  2540  			cfg.Placement = &Placement{}
  2541  		}
  2542  		cfg.Placement.Tags = append(cfg.Placement.Tags, req.Tags...)
  2543  	}
  2544  
  2545  	peers, e := cc.selectPeerGroup(cfg.Replicas+1, currCluster, &cfg, currPeers, 1, nil)
  2546  	if len(peers) <= cfg.Replicas {
  2547  		// since expanding in the same cluster did not yield a result, try in different cluster
  2548  		peers = nil
  2549  
  2550  		clusters := map[string]struct{}{}
  2551  		s.nodeToInfo.Range(func(_, ni interface{}) bool {
  2552  			if currCluster != ni.(nodeInfo).cluster {
  2553  				clusters[ni.(nodeInfo).cluster] = struct{}{}
  2554  			}
  2555  			return true
  2556  		})
  2557  		errs := &selectPeerError{}
  2558  		errs.accumulate(e)
  2559  		for cluster := range clusters {
  2560  			newPeers, e := cc.selectPeerGroup(cfg.Replicas, cluster, &cfg, nil, 0, nil)
  2561  			if len(newPeers) >= cfg.Replicas {
  2562  				peers = append([]string{}, currPeers...)
  2563  				peers = append(peers, newPeers[:cfg.Replicas]...)
  2564  				break
  2565  			}
  2566  			errs.accumulate(e)
  2567  		}
  2568  		if peers == nil {
  2569  			resp.Error = NewJSClusterNoPeersError(errs)
  2570  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2571  			return
  2572  		}
  2573  	}
  2574  
  2575  	cfg.Placement = origPlacement
  2576  
  2577  	s.Noticef("Requested move for stream '%s > %s' R=%d from %+v to %+v",
  2578  		streamName, accName, cfg.Replicas, s.peerSetToNames(currPeers), s.peerSetToNames(peers))
  2579  
  2580  	// We will always have peers and therefore never do a callout, therefore it is safe to call inline
  2581  	s.jsClusteredStreamUpdateRequest(&ciNew, targetAcc.(*Account), subject, reply, rmsg, &cfg, peers)
  2582  }
  2583  
  2584  // Request to have the metaleader move a stream on a peer to another
  2585  func (s *Server) jsLeaderServerStreamCancelMoveRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2586  	if c == nil || !s.JetStreamEnabled() {
  2587  		return
  2588  	}
  2589  
  2590  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2591  	if err != nil {
  2592  		s.Warnf(badAPIRequestT, msg)
  2593  		return
  2594  	}
  2595  
  2596  	js, cc := s.getJetStreamCluster()
  2597  	if js == nil || cc == nil || cc.meta == nil {
  2598  		return
  2599  	}
  2600  
  2601  	// Extra checks here but only leader is listening.
  2602  	js.mu.RLock()
  2603  	isLeader := cc.isLeader()
  2604  	js.mu.RUnlock()
  2605  
  2606  	if !isLeader {
  2607  		return
  2608  	}
  2609  
  2610  	var resp = JSApiStreamUpdateResponse{ApiResponse: ApiResponse{Type: JSApiStreamUpdateResponseType}}
  2611  
  2612  	accName := tokenAt(subject, 6)
  2613  	streamName := tokenAt(subject, 7)
  2614  
  2615  	targetAcc, ok := s.accounts.Load(accName)
  2616  	if !ok {
  2617  		resp.Error = NewJSNoAccountError()
  2618  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2619  		return
  2620  	}
  2621  
  2622  	streamFound := false
  2623  	cfg := StreamConfig{}
  2624  	currPeers := []string{}
  2625  	js.mu.Lock()
  2626  	streams, ok := cc.streams[accName]
  2627  	if ok {
  2628  		sa, ok := streams[streamName]
  2629  		if ok {
  2630  			cfg = *sa.Config
  2631  			streamFound = true
  2632  			currPeers = sa.Group.Peers
  2633  		}
  2634  	}
  2635  	js.mu.Unlock()
  2636  
  2637  	if !streamFound {
  2638  		resp.Error = NewJSStreamNotFoundError()
  2639  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2640  		return
  2641  	}
  2642  
  2643  	if len(currPeers) <= cfg.Replicas {
  2644  		resp.Error = NewJSStreamMoveNotInProgressError()
  2645  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2646  		return
  2647  	}
  2648  
  2649  	// make sure client is scoped to requested account
  2650  	ciNew := *(ci)
  2651  	ciNew.Account = accName
  2652  
  2653  	peers := currPeers[:cfg.Replicas]
  2654  
  2655  	// Remove placement in case tags don't match
  2656  	// This can happen if the move was initiated by modifying the tags.
  2657  	// This is an account operation.
  2658  	// This can NOT happen when the move was initiated by the system account.
  2659  	// There move honors the original tag list.
  2660  	if cfg.Placement != nil && len(cfg.Placement.Tags) != 0 {
  2661  	FOR_TAGCHECK:
  2662  		for _, peer := range peers {
  2663  			si, ok := s.nodeToInfo.Load(peer)
  2664  			if !ok {
  2665  				// can't verify tags, do the safe thing and error
  2666  				resp.Error = NewJSStreamGeneralError(
  2667  					fmt.Errorf("peer %s not present for tag validation", peer))
  2668  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2669  				return
  2670  			}
  2671  			nodeTags := si.(nodeInfo).tags
  2672  			for _, tag := range cfg.Placement.Tags {
  2673  				if !nodeTags.Contains(tag) {
  2674  					// clear placement as tags don't match
  2675  					cfg.Placement = nil
  2676  					break FOR_TAGCHECK
  2677  				}
  2678  			}
  2679  
  2680  		}
  2681  	}
  2682  
  2683  	s.Noticef("Requested cancel of move: R=%d '%s > %s' to peer set %+v and restore previous peer set %+v",
  2684  		cfg.Replicas, streamName, accName, s.peerSetToNames(currPeers), s.peerSetToNames(peers))
  2685  
  2686  	// We will always have peers and therefore never do a callout, therefore it is safe to call inline
  2687  	s.jsClusteredStreamUpdateRequest(&ciNew, targetAcc.(*Account), subject, reply, rmsg, &cfg, peers)
  2688  }
  2689  
  2690  // Request to have an account purged
  2691  func (s *Server) jsLeaderAccountPurgeRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2692  	if c == nil || !s.JetStreamEnabled() {
  2693  		return
  2694  	}
  2695  
  2696  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2697  	if err != nil {
  2698  		s.Warnf(badAPIRequestT, msg)
  2699  		return
  2700  	}
  2701  
  2702  	js := s.getJetStream()
  2703  	if js == nil {
  2704  		return
  2705  	}
  2706  
  2707  	accName := tokenAt(subject, 5)
  2708  
  2709  	var resp = JSApiAccountPurgeResponse{ApiResponse: ApiResponse{Type: JSApiAccountPurgeResponseType}}
  2710  
  2711  	if !s.JetStreamIsClustered() {
  2712  		var streams []*stream
  2713  		var ac *Account
  2714  		if ac, err = s.lookupAccount(accName); err == nil && ac != nil {
  2715  			streams = ac.streams()
  2716  		}
  2717  
  2718  		s.Noticef("Purge request for account %s (streams: %d, hasAccount: %t)",
  2719  			accName, len(streams), ac != nil)
  2720  
  2721  		for _, mset := range streams {
  2722  			err := mset.delete()
  2723  			if err != nil {
  2724  				resp.Error = NewJSStreamDeleteError(err)
  2725  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2726  				return
  2727  			}
  2728  		}
  2729  		if err := os.RemoveAll(filepath.Join(js.config.StoreDir, accName)); err != nil {
  2730  			resp.Error = NewJSStreamGeneralError(err)
  2731  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2732  			return
  2733  		}
  2734  		resp.Initiated = true
  2735  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2736  		return
  2737  	}
  2738  
  2739  	_, cc := s.getJetStreamCluster()
  2740  	if cc == nil || cc.meta == nil || !cc.isLeader() {
  2741  		return
  2742  	}
  2743  
  2744  	if js.isMetaRecovering() {
  2745  		// While in recovery mode, the data structures are not fully initialized
  2746  		resp.Error = NewJSClusterNotAvailError()
  2747  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2748  		return
  2749  	}
  2750  
  2751  	js.mu.RLock()
  2752  	ns, nc := 0, 0
  2753  	streams, hasAccount := cc.streams[accName]
  2754  	for _, osa := range streams {
  2755  		for _, oca := range osa.consumers {
  2756  			oca.deleted = true
  2757  			ca := &consumerAssignment{Group: oca.Group, Stream: oca.Stream, Name: oca.Name, Config: oca.Config, Subject: subject, Client: oca.Client}
  2758  			cc.meta.Propose(encodeDeleteConsumerAssignment(ca))
  2759  			nc++
  2760  		}
  2761  		sa := &streamAssignment{Group: osa.Group, Config: osa.Config, Subject: subject, Client: osa.Client}
  2762  		cc.meta.Propose(encodeDeleteStreamAssignment(sa))
  2763  		ns++
  2764  	}
  2765  	js.mu.RUnlock()
  2766  
  2767  	s.Noticef("Purge request for account %s (streams: %d, consumer: %d, hasAccount: %t)", accName, ns, nc, hasAccount)
  2768  
  2769  	resp.Initiated = true
  2770  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2771  }
  2772  
  2773  // Request to have the meta leader stepdown.
  2774  // These will only be received by the meta leader, so less checking needed.
  2775  func (s *Server) jsLeaderStepDownRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2776  	if c == nil || !s.JetStreamEnabled() {
  2777  		return
  2778  	}
  2779  
  2780  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2781  	if err != nil {
  2782  		s.Warnf(badAPIRequestT, msg)
  2783  		return
  2784  	}
  2785  
  2786  	js, cc := s.getJetStreamCluster()
  2787  	if js == nil || cc == nil || cc.meta == nil {
  2788  		return
  2789  	}
  2790  
  2791  	// Extra checks here but only leader is listening.
  2792  	js.mu.RLock()
  2793  	isLeader := cc.isLeader()
  2794  	js.mu.RUnlock()
  2795  
  2796  	if !isLeader {
  2797  		return
  2798  	}
  2799  
  2800  	var preferredLeader string
  2801  	var resp = JSApiLeaderStepDownResponse{ApiResponse: ApiResponse{Type: JSApiLeaderStepDownResponseType}}
  2802  
  2803  	if !isEmptyRequest(msg) {
  2804  		var req JSApiLeaderStepdownRequest
  2805  		if err := json.Unmarshal(msg, &req); err != nil {
  2806  			resp.Error = NewJSInvalidJSONError()
  2807  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2808  			return
  2809  		}
  2810  		if len(req.Placement.Tags) > 0 {
  2811  			// Tags currently not supported.
  2812  			resp.Error = NewJSClusterTagsError()
  2813  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2814  			return
  2815  		}
  2816  		cn := req.Placement.Cluster
  2817  		var peers []string
  2818  		ourID := cc.meta.ID()
  2819  		for _, p := range cc.meta.Peers() {
  2820  			if si, ok := s.nodeToInfo.Load(p.ID); ok && si != nil {
  2821  				if ni := si.(nodeInfo); ni.offline || ni.cluster != cn || p.ID == ourID {
  2822  					continue
  2823  				}
  2824  				peers = append(peers, p.ID)
  2825  			}
  2826  		}
  2827  		if len(peers) == 0 {
  2828  			resp.Error = NewJSClusterNoPeersError(fmt.Errorf("no replacement peer connected"))
  2829  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2830  			return
  2831  		}
  2832  		// Randomize and select.
  2833  		if len(peers) > 1 {
  2834  			rand.Shuffle(len(peers), func(i, j int) { peers[i], peers[j] = peers[j], peers[i] })
  2835  		}
  2836  		preferredLeader = peers[0]
  2837  	}
  2838  
  2839  	// Call actual stepdown.
  2840  	err = cc.meta.StepDown(preferredLeader)
  2841  	if err != nil {
  2842  		resp.Error = NewJSRaftGeneralError(err, Unless(err))
  2843  	} else {
  2844  		resp.Success = true
  2845  	}
  2846  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2847  }
  2848  
  2849  func isEmptyRequest(req []byte) bool {
  2850  	if len(req) == 0 {
  2851  		return true
  2852  	}
  2853  	if bytes.Equal(req, []byte("{}")) {
  2854  		return true
  2855  	}
  2856  	// If we are here we didn't get our simple match, but still could be valid.
  2857  	var v interface{}
  2858  	if err := json.Unmarshal(req, &v); err != nil {
  2859  		return false
  2860  	}
  2861  	vm, ok := v.(map[string]interface{})
  2862  	if !ok {
  2863  		return false
  2864  	}
  2865  	return len(vm) == 0
  2866  }
  2867  
  2868  // Request to delete a stream.
  2869  func (s *Server) jsStreamDeleteRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2870  	if c == nil || !s.JetStreamEnabled() {
  2871  		return
  2872  	}
  2873  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2874  	if err != nil {
  2875  		s.Warnf(badAPIRequestT, msg)
  2876  		return
  2877  	}
  2878  
  2879  	var resp = JSApiStreamDeleteResponse{ApiResponse: ApiResponse{Type: JSApiStreamDeleteResponseType}}
  2880  
  2881  	// Determine if we should proceed here when we are in clustered mode.
  2882  	if s.JetStreamIsClustered() {
  2883  		js, cc := s.getJetStreamCluster()
  2884  		if js == nil || cc == nil {
  2885  			return
  2886  		}
  2887  		if js.isLeaderless() {
  2888  			resp.Error = NewJSClusterNotAvailError()
  2889  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2890  			return
  2891  		}
  2892  		// Make sure we are meta leader.
  2893  		if !s.JetStreamIsLeader() {
  2894  			return
  2895  		}
  2896  	}
  2897  
  2898  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2899  		if doErr {
  2900  			resp.Error = NewJSNotEnabledForAccountError()
  2901  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2902  		}
  2903  		return
  2904  	}
  2905  
  2906  	if !isEmptyRequest(msg) {
  2907  		resp.Error = NewJSNotEmptyRequestError()
  2908  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2909  		return
  2910  	}
  2911  	stream := streamNameFromSubject(subject)
  2912  
  2913  	// Clustered.
  2914  	if s.JetStreamIsClustered() {
  2915  		s.jsClusteredStreamDeleteRequest(ci, acc, stream, subject, reply, msg)
  2916  		return
  2917  	}
  2918  
  2919  	mset, err := acc.lookupStream(stream)
  2920  	if err != nil {
  2921  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  2922  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2923  		return
  2924  	}
  2925  
  2926  	if err := mset.delete(); err != nil {
  2927  		resp.Error = NewJSStreamDeleteError(err, Unless(err))
  2928  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2929  		return
  2930  	}
  2931  	resp.Success = true
  2932  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  2933  }
  2934  
  2935  // Request to delete a message.
  2936  // This expects a stream sequence number as the msg body.
  2937  func (s *Server) jsMsgDeleteRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  2938  	if c == nil || !s.JetStreamEnabled() {
  2939  		return
  2940  	}
  2941  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  2942  	if err != nil {
  2943  		s.Warnf(badAPIRequestT, msg)
  2944  		return
  2945  	}
  2946  
  2947  	stream := tokenAt(subject, 6)
  2948  
  2949  	var resp = JSApiMsgDeleteResponse{ApiResponse: ApiResponse{Type: JSApiMsgDeleteResponseType}}
  2950  
  2951  	// If we are in clustered mode we need to be the stream leader to proceed.
  2952  	if s.JetStreamIsClustered() {
  2953  		// Check to make sure the stream is assigned.
  2954  		js, cc := s.getJetStreamCluster()
  2955  		if js == nil || cc == nil {
  2956  			return
  2957  		}
  2958  		if js.isLeaderless() {
  2959  			resp.Error = NewJSClusterNotAvailError()
  2960  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2961  			return
  2962  		}
  2963  
  2964  		js.mu.RLock()
  2965  		isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, stream)
  2966  		js.mu.RUnlock()
  2967  
  2968  		if isLeader && sa == nil {
  2969  			// We can't find the stream, so mimic what would be the errors below.
  2970  			if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2971  				if doErr {
  2972  					resp.Error = NewJSNotEnabledForAccountError()
  2973  					s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2974  				}
  2975  				return
  2976  			}
  2977  			// No stream present.
  2978  			resp.Error = NewJSStreamNotFoundError()
  2979  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2980  			return
  2981  		} else if sa == nil {
  2982  			return
  2983  		}
  2984  
  2985  		// Check to see if we are a member of the group and if the group has no leader.
  2986  		if js.isGroupLeaderless(sa.Group) {
  2987  			resp.Error = NewJSClusterNotAvailError()
  2988  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  2989  			return
  2990  		}
  2991  
  2992  		// We have the stream assigned and a leader, so only the stream leader should answer.
  2993  		if !acc.JetStreamIsStreamLeader(stream) {
  2994  			return
  2995  		}
  2996  	}
  2997  
  2998  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  2999  		if doErr {
  3000  			resp.Error = NewJSNotEnabledForAccountError()
  3001  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3002  		}
  3003  		return
  3004  	}
  3005  	if isEmptyRequest(msg) {
  3006  		resp.Error = NewJSBadRequestError()
  3007  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3008  		return
  3009  	}
  3010  	var req JSApiMsgDeleteRequest
  3011  	if err := json.Unmarshal(msg, &req); err != nil {
  3012  		resp.Error = NewJSInvalidJSONError()
  3013  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3014  		return
  3015  	}
  3016  
  3017  	mset, err := acc.lookupStream(stream)
  3018  	if err != nil {
  3019  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  3020  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3021  		return
  3022  	}
  3023  	if mset.cfg.Sealed {
  3024  		resp.Error = NewJSStreamSealedError()
  3025  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3026  		return
  3027  	}
  3028  	if mset.cfg.DenyDelete {
  3029  		resp.Error = NewJSStreamMsgDeleteFailedError(errors.New("message delete not permitted"))
  3030  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3031  		return
  3032  	}
  3033  
  3034  	if s.JetStreamIsClustered() {
  3035  		s.jsClusteredMsgDeleteRequest(ci, acc, mset, stream, subject, reply, &req, rmsg)
  3036  		return
  3037  	}
  3038  
  3039  	var removed bool
  3040  	if req.NoErase {
  3041  		removed, err = mset.removeMsg(req.Seq)
  3042  	} else {
  3043  		removed, err = mset.eraseMsg(req.Seq)
  3044  	}
  3045  	if err != nil {
  3046  		resp.Error = NewJSStreamMsgDeleteFailedError(err, Unless(err))
  3047  	} else if !removed {
  3048  		resp.Error = NewJSSequenceNotFoundError(req.Seq)
  3049  	} else {
  3050  		resp.Success = true
  3051  	}
  3052  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  3053  }
  3054  
  3055  // Request to get a raw stream message.
  3056  func (s *Server) jsMsgGetRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  3057  	if c == nil || !s.JetStreamEnabled() {
  3058  		return
  3059  	}
  3060  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  3061  	if err != nil {
  3062  		s.Warnf(badAPIRequestT, msg)
  3063  		return
  3064  	}
  3065  
  3066  	stream := tokenAt(subject, 6)
  3067  
  3068  	var resp = JSApiMsgGetResponse{ApiResponse: ApiResponse{Type: JSApiMsgGetResponseType}}
  3069  
  3070  	// If we are in clustered mode we need to be the stream leader to proceed.
  3071  	if s.JetStreamIsClustered() {
  3072  		// Check to make sure the stream is assigned.
  3073  		js, cc := s.getJetStreamCluster()
  3074  		if js == nil || cc == nil {
  3075  			return
  3076  		}
  3077  		if js.isLeaderless() {
  3078  			resp.Error = NewJSClusterNotAvailError()
  3079  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3080  			return
  3081  		}
  3082  
  3083  		js.mu.RLock()
  3084  		isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, stream)
  3085  		js.mu.RUnlock()
  3086  
  3087  		if isLeader && sa == nil {
  3088  			// We can't find the stream, so mimic what would be the errors below.
  3089  			if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3090  				if doErr {
  3091  					resp.Error = NewJSNotEnabledForAccountError()
  3092  					s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3093  				}
  3094  				return
  3095  			}
  3096  			// No stream present.
  3097  			resp.Error = NewJSStreamNotFoundError()
  3098  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3099  			return
  3100  		} else if sa == nil {
  3101  			return
  3102  		}
  3103  
  3104  		// Check to see if we are a member of the group and if the group has no leader.
  3105  		if js.isGroupLeaderless(sa.Group) {
  3106  			resp.Error = NewJSClusterNotAvailError()
  3107  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3108  			return
  3109  		}
  3110  
  3111  		// We have the stream assigned and a leader, so only the stream leader should answer.
  3112  		if !acc.JetStreamIsStreamLeader(stream) {
  3113  			return
  3114  		}
  3115  	}
  3116  
  3117  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3118  		if doErr {
  3119  			resp.Error = NewJSNotEnabledForAccountError()
  3120  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3121  		}
  3122  		return
  3123  	}
  3124  	if isEmptyRequest(msg) {
  3125  		resp.Error = NewJSBadRequestError()
  3126  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3127  		return
  3128  	}
  3129  	var req JSApiMsgGetRequest
  3130  	if err := json.Unmarshal(msg, &req); err != nil {
  3131  		resp.Error = NewJSInvalidJSONError()
  3132  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3133  		return
  3134  	}
  3135  
  3136  	// This version does not support batch.
  3137  	if req.Batch > 0 || req.MaxBytes > 0 {
  3138  		resp.Error = NewJSBadRequestError()
  3139  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3140  		return
  3141  	}
  3142  
  3143  	// Check that we do not have both options set.
  3144  	if req.Seq > 0 && req.LastFor != _EMPTY_ || req.Seq == 0 && req.LastFor == _EMPTY_ && req.NextFor == _EMPTY_ {
  3145  		resp.Error = NewJSBadRequestError()
  3146  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3147  		return
  3148  	}
  3149  	// Check that both last and next not both set.
  3150  	if req.LastFor != _EMPTY_ && req.NextFor != _EMPTY_ {
  3151  		resp.Error = NewJSBadRequestError()
  3152  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3153  		return
  3154  	}
  3155  
  3156  	mset, err := acc.lookupStream(stream)
  3157  	if err != nil {
  3158  		resp.Error = NewJSStreamNotFoundError()
  3159  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3160  		return
  3161  	}
  3162  
  3163  	var svp StoreMsg
  3164  	var sm *StoreMsg
  3165  
  3166  	if req.Seq > 0 && req.NextFor == _EMPTY_ {
  3167  		sm, err = mset.store.LoadMsg(req.Seq, &svp)
  3168  	} else if req.NextFor != _EMPTY_ {
  3169  		sm, _, err = mset.store.LoadNextMsg(req.NextFor, subjectHasWildcard(req.NextFor), req.Seq, &svp)
  3170  	} else {
  3171  		sm, err = mset.store.LoadLastMsg(req.LastFor, &svp)
  3172  	}
  3173  	if err != nil {
  3174  		resp.Error = NewJSNoMessageFoundError()
  3175  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3176  		return
  3177  	}
  3178  	resp.Message = &StoredMsg{
  3179  		Subject:  sm.subj,
  3180  		Sequence: sm.seq,
  3181  		Header:   sm.hdr,
  3182  		Data:     sm.msg,
  3183  		Time:     time.Unix(0, sm.ts).UTC(),
  3184  	}
  3185  
  3186  	// Don't send response through API layer for this call.
  3187  	s.sendInternalAccountMsg(nil, reply, s.jsonResponse(resp))
  3188  }
  3189  
  3190  // Request to purge a stream.
  3191  func (s *Server) jsStreamPurgeRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  3192  	if c == nil || !s.JetStreamEnabled() {
  3193  		return
  3194  	}
  3195  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  3196  	if err != nil {
  3197  		s.Warnf(badAPIRequestT, msg)
  3198  		return
  3199  	}
  3200  
  3201  	stream := streamNameFromSubject(subject)
  3202  
  3203  	var resp = JSApiStreamPurgeResponse{ApiResponse: ApiResponse{Type: JSApiStreamPurgeResponseType}}
  3204  
  3205  	// If we are in clustered mode we need to be the stream leader to proceed.
  3206  	if s.JetStreamIsClustered() {
  3207  		// Check to make sure the stream is assigned.
  3208  		js, cc := s.getJetStreamCluster()
  3209  		if js == nil || cc == nil {
  3210  			return
  3211  		}
  3212  
  3213  		js.mu.RLock()
  3214  		isLeader, sa := cc.isLeader(), js.streamAssignment(acc.Name, stream)
  3215  		js.mu.RUnlock()
  3216  
  3217  		if isLeader && sa == nil {
  3218  			// We can't find the stream, so mimic what would be the errors below.
  3219  			if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3220  				if doErr {
  3221  					resp.Error = NewJSNotEnabledForAccountError()
  3222  					s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3223  				}
  3224  				return
  3225  			}
  3226  			// No stream present.
  3227  			resp.Error = NewJSStreamNotFoundError()
  3228  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3229  			return
  3230  		} else if sa == nil {
  3231  			if js.isLeaderless() {
  3232  				resp.Error = NewJSClusterNotAvailError()
  3233  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3234  			}
  3235  			return
  3236  		}
  3237  
  3238  		// Check to see if we are a member of the group and if the group has no leader.
  3239  		if js.isGroupLeaderless(sa.Group) {
  3240  			resp.Error = NewJSClusterNotAvailError()
  3241  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3242  			return
  3243  		}
  3244  
  3245  		// We have the stream assigned and a leader, so only the stream leader should answer.
  3246  		if !acc.JetStreamIsStreamLeader(stream) {
  3247  			if js.isLeaderless() {
  3248  				resp.Error = NewJSClusterNotAvailError()
  3249  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3250  			}
  3251  			return
  3252  		}
  3253  	}
  3254  
  3255  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3256  		if doErr {
  3257  			resp.Error = NewJSNotEnabledForAccountError()
  3258  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3259  		}
  3260  		return
  3261  	}
  3262  
  3263  	var purgeRequest *JSApiStreamPurgeRequest
  3264  	if !isEmptyRequest(msg) {
  3265  		var req JSApiStreamPurgeRequest
  3266  		if err := json.Unmarshal(msg, &req); err != nil {
  3267  			resp.Error = NewJSInvalidJSONError()
  3268  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3269  			return
  3270  		}
  3271  		if req.Sequence > 0 && req.Keep > 0 {
  3272  			resp.Error = NewJSBadRequestError()
  3273  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3274  			return
  3275  		}
  3276  		purgeRequest = &req
  3277  	}
  3278  
  3279  	mset, err := acc.lookupStream(stream)
  3280  	if err != nil {
  3281  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  3282  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3283  		return
  3284  	}
  3285  	if mset.cfg.Sealed {
  3286  		resp.Error = NewJSStreamSealedError()
  3287  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3288  		return
  3289  	}
  3290  	if mset.cfg.DenyPurge {
  3291  		resp.Error = NewJSStreamPurgeFailedError(errors.New("stream purge not permitted"))
  3292  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3293  		return
  3294  	}
  3295  
  3296  	if s.JetStreamIsClustered() {
  3297  		s.jsClusteredStreamPurgeRequest(ci, acc, mset, stream, subject, reply, rmsg, purgeRequest)
  3298  		return
  3299  	}
  3300  
  3301  	purged, err := mset.purge(purgeRequest)
  3302  	if err != nil {
  3303  		resp.Error = NewJSStreamGeneralError(err, Unless(err))
  3304  	} else {
  3305  		resp.Purged = purged
  3306  		resp.Success = true
  3307  	}
  3308  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  3309  }
  3310  
  3311  func (acc *Account) jsNonClusteredStreamLimitsCheck(cfg *StreamConfig) *ApiError {
  3312  	selectedLimits, tier, jsa, apiErr := acc.selectLimits(cfg)
  3313  	if apiErr != nil {
  3314  		return apiErr
  3315  	}
  3316  	jsa.mu.RLock()
  3317  	defer jsa.mu.RUnlock()
  3318  	if selectedLimits.MaxStreams > 0 && jsa.countStreams(tier, cfg) >= selectedLimits.MaxStreams {
  3319  		return NewJSMaximumStreamsLimitError()
  3320  	}
  3321  	reserved := jsa.tieredReservation(tier, cfg)
  3322  	if err := jsa.js.checkAllLimits(selectedLimits, cfg, reserved, 0); err != nil {
  3323  		return NewJSStreamLimitsError(err, Unless(err))
  3324  	}
  3325  	return nil
  3326  }
  3327  
  3328  // Request to restore a stream.
  3329  func (s *Server) jsStreamRestoreRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  3330  	if c == nil || !s.JetStreamIsLeader() {
  3331  		return
  3332  	}
  3333  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  3334  	if err != nil {
  3335  		s.Warnf(badAPIRequestT, msg)
  3336  		return
  3337  	}
  3338  
  3339  	var resp = JSApiStreamRestoreResponse{ApiResponse: ApiResponse{Type: JSApiStreamRestoreResponseType}}
  3340  	if !acc.JetStreamEnabled() {
  3341  		resp.Error = NewJSNotEnabledForAccountError()
  3342  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3343  		return
  3344  	}
  3345  	if isEmptyRequest(msg) {
  3346  		resp.Error = NewJSBadRequestError()
  3347  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3348  		return
  3349  	}
  3350  
  3351  	var req JSApiStreamRestoreRequest
  3352  	if err := json.Unmarshal(msg, &req); err != nil {
  3353  		resp.Error = NewJSInvalidJSONError()
  3354  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3355  		return
  3356  	}
  3357  
  3358  	stream := streamNameFromSubject(subject)
  3359  
  3360  	if stream != req.Config.Name && req.Config.Name == _EMPTY_ {
  3361  		req.Config.Name = stream
  3362  	}
  3363  
  3364  	// check stream config at the start of the restore process, not at the end
  3365  	cfg, apiErr := s.checkStreamCfg(&req.Config, acc)
  3366  	if apiErr != nil {
  3367  		resp.Error = apiErr
  3368  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3369  		return
  3370  	}
  3371  
  3372  	if s.JetStreamIsClustered() {
  3373  		s.jsClusteredStreamRestoreRequest(ci, acc, &req, stream, subject, reply, rmsg)
  3374  		return
  3375  	}
  3376  
  3377  	if err := acc.jsNonClusteredStreamLimitsCheck(&cfg); err != nil {
  3378  		resp.Error = err
  3379  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3380  		return
  3381  	}
  3382  
  3383  	if _, err := acc.lookupStream(stream); err == nil {
  3384  		resp.Error = NewJSStreamNameExistRestoreFailedError()
  3385  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3386  		return
  3387  	}
  3388  
  3389  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3390  		if doErr {
  3391  			resp.Error = NewJSNotEnabledForAccountError()
  3392  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3393  		}
  3394  		return
  3395  	}
  3396  
  3397  	s.processStreamRestore(ci, acc, &req.Config, subject, reply, string(msg))
  3398  }
  3399  
  3400  func (s *Server) processStreamRestore(ci *ClientInfo, acc *Account, cfg *StreamConfig, subject, reply, msg string) <-chan error {
  3401  	js := s.getJetStream()
  3402  
  3403  	var resp = JSApiStreamRestoreResponse{ApiResponse: ApiResponse{Type: JSApiStreamRestoreResponseType}}
  3404  
  3405  	snapDir := filepath.Join(js.config.StoreDir, snapStagingDir)
  3406  	if _, err := os.Stat(snapDir); os.IsNotExist(err) {
  3407  		if err := os.MkdirAll(snapDir, defaultDirPerms); err != nil {
  3408  			resp.Error = &ApiError{Code: 503, Description: "JetStream unable to create temp storage for restore"}
  3409  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3410  			return nil
  3411  		}
  3412  	}
  3413  
  3414  	tfile, err := os.CreateTemp(snapDir, "js-restore-")
  3415  	if err != nil {
  3416  		resp.Error = NewJSTempStorageFailedError()
  3417  		s.sendAPIErrResponse(ci, acc, subject, reply, msg, s.jsonResponse(&resp))
  3418  		return nil
  3419  	}
  3420  
  3421  	streamName := cfg.Name
  3422  	s.Noticef("Starting restore for stream '%s > %s'", acc.Name, streamName)
  3423  
  3424  	start := time.Now().UTC()
  3425  	domain := s.getOpts().JetStreamDomain
  3426  	s.publishAdvisory(acc, JSAdvisoryStreamRestoreCreatePre+"."+streamName, &JSRestoreCreateAdvisory{
  3427  		TypedEvent: TypedEvent{
  3428  			Type: JSRestoreCreateAdvisoryType,
  3429  			ID:   nuid.Next(),
  3430  			Time: start,
  3431  		},
  3432  		Stream: streamName,
  3433  		Client: ci,
  3434  		Domain: domain,
  3435  	})
  3436  
  3437  	// Create our internal subscription to accept the snapshot.
  3438  	restoreSubj := fmt.Sprintf(jsRestoreDeliverT, streamName, nuid.Next())
  3439  
  3440  	type result struct {
  3441  		err   error
  3442  		reply string
  3443  	}
  3444  
  3445  	// For signaling to upper layers.
  3446  	resultCh := make(chan result, 1)
  3447  	activeQ := newIPQueue[int](s, fmt.Sprintf("[ACC:%s] stream '%s' restore", acc.Name, streamName)) // of int
  3448  
  3449  	var total int
  3450  
  3451  	// FIXME(dlc) - Probably take out of network path eventually due to disk I/O?
  3452  	processChunk := func(sub *subscription, c *client, _ *Account, subject, reply string, msg []byte) {
  3453  		// We require reply subjects to communicate back failures, flow etc. If they do not have one log and cancel.
  3454  		if reply == _EMPTY_ {
  3455  			sub.client.processUnsub(sub.sid)
  3456  			resultCh <- result{
  3457  				fmt.Errorf("restore for stream '%s > %s' requires reply subject for each chunk", acc.Name, streamName),
  3458  				reply,
  3459  			}
  3460  			return
  3461  		}
  3462  		// Account client messages have \r\n on end. This is an error.
  3463  		if len(msg) < LEN_CR_LF {
  3464  			sub.client.processUnsub(sub.sid)
  3465  			resultCh <- result{
  3466  				fmt.Errorf("restore for stream '%s > %s' received short chunk", acc.Name, streamName),
  3467  				reply,
  3468  			}
  3469  			return
  3470  		}
  3471  		// Adjust.
  3472  		msg = msg[:len(msg)-LEN_CR_LF]
  3473  
  3474  		// This means we are complete with our transfer from the client.
  3475  		if len(msg) == 0 {
  3476  			s.Debugf("Finished staging restore for stream '%s > %s'", acc.Name, streamName)
  3477  			resultCh <- result{err, reply}
  3478  			return
  3479  		}
  3480  
  3481  		// We track total and check on server limits.
  3482  		// TODO(dlc) - We could check apriori and cancel initial request if we know it won't fit.
  3483  		total += len(msg)
  3484  		if js.wouldExceedLimits(FileStorage, total) {
  3485  			s.resourcesExceededError()
  3486  			resultCh <- result{NewJSInsufficientResourcesError(), reply}
  3487  			return
  3488  		}
  3489  
  3490  		// Append chunk to temp file. Mark as issue if we encounter an error.
  3491  		if n, err := tfile.Write(msg); n != len(msg) || err != nil {
  3492  			resultCh <- result{err, reply}
  3493  			if reply != _EMPTY_ {
  3494  				s.sendInternalAccountMsg(acc, reply, "-ERR 'storage failure during restore'")
  3495  			}
  3496  			return
  3497  		}
  3498  
  3499  		activeQ.push(len(msg))
  3500  
  3501  		s.sendInternalAccountMsg(acc, reply, nil)
  3502  	}
  3503  
  3504  	sub, err := acc.subscribeInternal(restoreSubj, processChunk)
  3505  	if err != nil {
  3506  		tfile.Close()
  3507  		os.Remove(tfile.Name())
  3508  		resp.Error = NewJSRestoreSubscribeFailedError(err, restoreSubj)
  3509  		s.sendAPIErrResponse(ci, acc, subject, reply, msg, s.jsonResponse(&resp))
  3510  		return nil
  3511  	}
  3512  
  3513  	// Mark the subject so the end user knows where to send the snapshot chunks.
  3514  	resp.DeliverSubject = restoreSubj
  3515  	s.sendAPIResponse(ci, acc, subject, reply, msg, s.jsonResponse(resp))
  3516  
  3517  	doneCh := make(chan error, 1)
  3518  
  3519  	// Monitor the progress from another Go routine.
  3520  	s.startGoRoutine(func() {
  3521  		defer s.grWG.Done()
  3522  		defer func() {
  3523  			tfile.Close()
  3524  			os.Remove(tfile.Name())
  3525  			sub.client.processUnsub(sub.sid)
  3526  			activeQ.unregister()
  3527  		}()
  3528  
  3529  		const activityInterval = 5 * time.Second
  3530  		notActive := time.NewTimer(activityInterval)
  3531  		defer notActive.Stop()
  3532  
  3533  		total := 0
  3534  		for {
  3535  			select {
  3536  			case result := <-resultCh:
  3537  				err := result.err
  3538  				var mset *stream
  3539  
  3540  				// If we staged properly go ahead and do restore now.
  3541  				if err == nil {
  3542  					s.Debugf("Finalizing restore for stream '%s > %s'", acc.Name, streamName)
  3543  					tfile.Seek(0, 0)
  3544  					mset, err = acc.RestoreStream(cfg, tfile)
  3545  				} else {
  3546  					errStr := err.Error()
  3547  					tmp := []rune(errStr)
  3548  					tmp[0] = unicode.ToUpper(tmp[0])
  3549  					s.Warnf(errStr)
  3550  				}
  3551  
  3552  				end := time.Now().UTC()
  3553  
  3554  				// TODO(rip) - Should this have the error code in it??
  3555  				s.publishAdvisory(acc, JSAdvisoryStreamRestoreCompletePre+"."+streamName, &JSRestoreCompleteAdvisory{
  3556  					TypedEvent: TypedEvent{
  3557  						Type: JSRestoreCompleteAdvisoryType,
  3558  						ID:   nuid.Next(),
  3559  						Time: end,
  3560  					},
  3561  					Stream: streamName,
  3562  					Start:  start,
  3563  					End:    end,
  3564  					Bytes:  int64(total),
  3565  					Client: ci,
  3566  					Domain: domain,
  3567  				})
  3568  
  3569  				var resp = JSApiStreamCreateResponse{ApiResponse: ApiResponse{Type: JSApiStreamCreateResponseType}}
  3570  
  3571  				if err != nil {
  3572  					resp.Error = NewJSStreamRestoreError(err, Unless(err))
  3573  					s.Warnf("Restore failed for %s for stream '%s > %s' in %v",
  3574  						friendlyBytes(int64(total)), streamName, acc.Name, end.Sub(start))
  3575  				} else {
  3576  					resp.StreamInfo = &StreamInfo{
  3577  						Created:   mset.createdTime(),
  3578  						State:     mset.state(),
  3579  						Config:    mset.config(),
  3580  						TimeStamp: time.Now().UTC(),
  3581  					}
  3582  					s.Noticef("Completed restore of %s for stream '%s > %s' in %v",
  3583  						friendlyBytes(int64(total)), streamName, acc.Name, end.Sub(start).Round(time.Millisecond))
  3584  				}
  3585  
  3586  				// On the last EOF, send back the stream info or error status.
  3587  				s.sendInternalAccountMsg(acc, result.reply, s.jsonResponse(&resp))
  3588  				// Signal to the upper layers.
  3589  				doneCh <- err
  3590  				return
  3591  			case <-activeQ.ch:
  3592  				if n, ok := activeQ.popOne(); ok {
  3593  					total += n
  3594  					notActive.Reset(activityInterval)
  3595  				}
  3596  			case <-notActive.C:
  3597  				err := fmt.Errorf("restore for stream '%s > %s' is stalled", acc, streamName)
  3598  				doneCh <- err
  3599  				return
  3600  			}
  3601  		}
  3602  	})
  3603  
  3604  	return doneCh
  3605  }
  3606  
  3607  // Process a snapshot request.
  3608  func (s *Server) jsStreamSnapshotRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  3609  	if c == nil || !s.JetStreamEnabled() {
  3610  		return
  3611  	}
  3612  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  3613  	if err != nil {
  3614  		s.Warnf(badAPIRequestT, msg)
  3615  		return
  3616  	}
  3617  
  3618  	smsg := string(msg)
  3619  	stream := streamNameFromSubject(subject)
  3620  
  3621  	// If we are in clustered mode we need to be the stream leader to proceed.
  3622  	if s.JetStreamIsClustered() && !acc.JetStreamIsStreamLeader(stream) {
  3623  		return
  3624  	}
  3625  
  3626  	var resp = JSApiStreamSnapshotResponse{ApiResponse: ApiResponse{Type: JSApiStreamSnapshotResponseType}}
  3627  	if !acc.JetStreamEnabled() {
  3628  		resp.Error = NewJSNotEnabledForAccountError()
  3629  		s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3630  		return
  3631  	}
  3632  	if isEmptyRequest(msg) {
  3633  		resp.Error = NewJSBadRequestError()
  3634  		s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3635  		return
  3636  	}
  3637  
  3638  	mset, err := acc.lookupStream(stream)
  3639  	if err != nil {
  3640  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  3641  		s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3642  		return
  3643  	}
  3644  
  3645  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3646  		if doErr {
  3647  			resp.Error = NewJSNotEnabledForAccountError()
  3648  			s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3649  		}
  3650  		return
  3651  	}
  3652  
  3653  	var req JSApiStreamSnapshotRequest
  3654  	if err := json.Unmarshal(msg, &req); err != nil {
  3655  		resp.Error = NewJSInvalidJSONError()
  3656  		s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3657  		return
  3658  	}
  3659  	if !IsValidSubject(req.DeliverSubject) {
  3660  		resp.Error = NewJSSnapshotDeliverSubjectInvalidError()
  3661  		s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3662  		return
  3663  	}
  3664  
  3665  	// We will do the snapshot in a go routine as well since check msgs may
  3666  	// stall this go routine.
  3667  	go func() {
  3668  		if req.CheckMsgs {
  3669  			s.Noticef("Starting health check and snapshot for stream '%s > %s'", mset.jsa.account.Name, mset.name())
  3670  		} else {
  3671  			s.Noticef("Starting snapshot for stream '%s > %s'", mset.jsa.account.Name, mset.name())
  3672  		}
  3673  
  3674  		start := time.Now().UTC()
  3675  
  3676  		sr, err := mset.snapshot(0, req.CheckMsgs, !req.NoConsumers)
  3677  		if err != nil {
  3678  			s.Warnf("Snapshot of stream '%s > %s' failed: %v", mset.jsa.account.Name, mset.name(), err)
  3679  			resp.Error = NewJSStreamSnapshotError(err, Unless(err))
  3680  			s.sendAPIErrResponse(ci, acc, subject, reply, smsg, s.jsonResponse(&resp))
  3681  			return
  3682  		}
  3683  
  3684  		config := mset.config()
  3685  		resp.State = &sr.State
  3686  		resp.Config = &config
  3687  
  3688  		s.sendAPIResponse(ci, acc, subject, reply, smsg, s.jsonResponse(resp))
  3689  
  3690  		s.publishAdvisory(acc, JSAdvisoryStreamSnapshotCreatePre+"."+mset.name(), &JSSnapshotCreateAdvisory{
  3691  			TypedEvent: TypedEvent{
  3692  				Type: JSSnapshotCreatedAdvisoryType,
  3693  				ID:   nuid.Next(),
  3694  				Time: time.Now().UTC(),
  3695  			},
  3696  			Stream: mset.name(),
  3697  			State:  sr.State,
  3698  			Client: ci,
  3699  			Domain: s.getOpts().JetStreamDomain,
  3700  		})
  3701  
  3702  		// Now do the real streaming.
  3703  		s.streamSnapshot(ci, acc, mset, sr, &req)
  3704  
  3705  		end := time.Now().UTC()
  3706  
  3707  		s.publishAdvisory(acc, JSAdvisoryStreamSnapshotCompletePre+"."+mset.name(), &JSSnapshotCompleteAdvisory{
  3708  			TypedEvent: TypedEvent{
  3709  				Type: JSSnapshotCompleteAdvisoryType,
  3710  				ID:   nuid.Next(),
  3711  				Time: end,
  3712  			},
  3713  			Stream: mset.name(),
  3714  			Start:  start,
  3715  			End:    end,
  3716  			Client: ci,
  3717  			Domain: s.getOpts().JetStreamDomain,
  3718  		})
  3719  
  3720  		s.Noticef("Completed snapshot of %s for stream '%s > %s' in %v",
  3721  			friendlyBytes(int64(sr.State.Bytes)),
  3722  			mset.jsa.account.Name,
  3723  			mset.name(),
  3724  			end.Sub(start))
  3725  	}()
  3726  }
  3727  
  3728  // Default chunk size for now.
  3729  const defaultSnapshotChunkSize = 128 * 1024
  3730  const defaultSnapshotWindowSize = 8 * 1024 * 1024 // 8MB
  3731  
  3732  // streamSnapshot will stream out our snapshot to the reply subject.
  3733  func (s *Server) streamSnapshot(ci *ClientInfo, acc *Account, mset *stream, sr *SnapshotResult, req *JSApiStreamSnapshotRequest) {
  3734  	chunkSize := req.ChunkSize
  3735  	if chunkSize == 0 {
  3736  		chunkSize = defaultSnapshotChunkSize
  3737  	}
  3738  	// Setup for the chunk stream.
  3739  	reply := req.DeliverSubject
  3740  	r := sr.Reader
  3741  	defer r.Close()
  3742  
  3743  	// Check interest for the snapshot deliver subject.
  3744  	inch := make(chan bool, 1)
  3745  	acc.sl.RegisterNotification(req.DeliverSubject, inch)
  3746  	defer acc.sl.ClearNotification(req.DeliverSubject, inch)
  3747  	hasInterest := <-inch
  3748  	if !hasInterest {
  3749  		// Allow 2 seconds or so for interest to show up.
  3750  		select {
  3751  		case <-inch:
  3752  		case <-time.After(2 * time.Second):
  3753  		}
  3754  	}
  3755  
  3756  	// Create our ack flow handler.
  3757  	// This is very simple for now.
  3758  	ackSize := defaultSnapshotWindowSize / chunkSize
  3759  	if ackSize < 8 {
  3760  		ackSize = 8
  3761  	} else if ackSize > 8*1024 {
  3762  		ackSize = 8 * 1024
  3763  	}
  3764  	acks := make(chan struct{}, ackSize)
  3765  	acks <- struct{}{}
  3766  
  3767  	// Track bytes outstanding.
  3768  	var out int32
  3769  
  3770  	// We will place sequence number and size of chunk sent in the reply.
  3771  	ackSubj := fmt.Sprintf(jsSnapshotAckT, mset.name(), nuid.Next())
  3772  	ackSub, _ := mset.subscribeInternal(ackSubj+".>", func(_ *subscription, _ *client, _ *Account, subject, _ string, _ []byte) {
  3773  		cs, _ := strconv.Atoi(tokenAt(subject, 6))
  3774  		// This is very crude and simple, but ok for now.
  3775  		// This only matters when sending multiple chunks.
  3776  		if atomic.AddInt32(&out, int32(-cs)) < defaultSnapshotWindowSize {
  3777  			select {
  3778  			case acks <- struct{}{}:
  3779  			default:
  3780  			}
  3781  		}
  3782  	})
  3783  	defer mset.unsubscribe(ackSub)
  3784  
  3785  	// TODO(dlc) - Add in NATS-Chunked-Sequence header
  3786  	var hdr []byte
  3787  	for index := 1; ; index++ {
  3788  		chunk := make([]byte, chunkSize)
  3789  		n, err := r.Read(chunk)
  3790  		chunk = chunk[:n]
  3791  		if err != nil {
  3792  			if n > 0 {
  3793  				mset.outq.send(newJSPubMsg(reply, _EMPTY_, _EMPTY_, nil, chunk, nil, 0))
  3794  			}
  3795  			break
  3796  		}
  3797  
  3798  		// Wait on acks for flow control if past our window size.
  3799  		// Wait up to 10ms for now if no acks received.
  3800  		if atomic.LoadInt32(&out) > defaultSnapshotWindowSize {
  3801  			select {
  3802  			case <-acks:
  3803  				// ok to proceed.
  3804  			case <-inch:
  3805  				// Lost interest
  3806  				hdr = []byte("NATS/1.0 408 No Interest\r\n\r\n")
  3807  				goto done
  3808  			case <-time.After(2 * time.Second):
  3809  				hdr = []byte("NATS/1.0 408 No Flow Response\r\n\r\n")
  3810  				goto done
  3811  			}
  3812  		}
  3813  		ackReply := fmt.Sprintf("%s.%d.%d", ackSubj, len(chunk), index)
  3814  		if hdr == nil {
  3815  			hdr = []byte("NATS/1.0 204\r\n\r\n")
  3816  		}
  3817  		mset.outq.send(newJSPubMsg(reply, _EMPTY_, ackReply, nil, chunk, nil, 0))
  3818  		atomic.AddInt32(&out, int32(len(chunk)))
  3819  	}
  3820  done:
  3821  	// Send last EOF
  3822  	// TODO(dlc) - place hash in header
  3823  	mset.outq.send(newJSPubMsg(reply, _EMPTY_, _EMPTY_, hdr, nil, nil, 0))
  3824  }
  3825  
  3826  // For determining consumer request type.
  3827  type ccReqType uint8
  3828  
  3829  const (
  3830  	ccNew = iota
  3831  	ccLegacyEphemeral
  3832  	ccLegacyDurable
  3833  )
  3834  
  3835  // Request to create a consumer where stream and optional consumer name are part of the subject, and optional
  3836  // filtered subjects can be at the tail end.
  3837  // Assumes stream and consumer names are single tokens.
  3838  func (s *Server) jsConsumerCreateRequest(sub *subscription, c *client, a *Account, subject, reply string, rmsg []byte) {
  3839  	if c == nil || !s.JetStreamEnabled() {
  3840  		return
  3841  	}
  3842  
  3843  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  3844  	if err != nil {
  3845  		s.Warnf(badAPIRequestT, msg)
  3846  		return
  3847  	}
  3848  
  3849  	var resp = JSApiConsumerCreateResponse{ApiResponse: ApiResponse{Type: JSApiConsumerCreateResponseType}}
  3850  
  3851  	var req CreateConsumerRequest
  3852  	if err := json.Unmarshal(msg, &req); err != nil {
  3853  		resp.Error = NewJSInvalidJSONError()
  3854  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3855  		return
  3856  	}
  3857  
  3858  	var js *jetStream
  3859  	isClustered := s.JetStreamIsClustered()
  3860  
  3861  	// Determine if we should proceed here when we are in clustered mode.
  3862  	if isClustered {
  3863  		if req.Config.Direct {
  3864  			// Check to see if we have this stream and are the stream leader.
  3865  			if !acc.JetStreamIsStreamLeader(streamNameFromSubject(subject)) {
  3866  				return
  3867  			}
  3868  		} else {
  3869  			var cc *jetStreamCluster
  3870  			js, cc = s.getJetStreamCluster()
  3871  			if js == nil || cc == nil {
  3872  				return
  3873  			}
  3874  			if js.isLeaderless() {
  3875  				resp.Error = NewJSClusterNotAvailError()
  3876  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3877  				return
  3878  			}
  3879  			// Make sure we are meta leader.
  3880  			if !s.JetStreamIsLeader() {
  3881  				return
  3882  			}
  3883  		}
  3884  	}
  3885  
  3886  	var streamName, consumerName, filteredSubject string
  3887  	var rt ccReqType
  3888  
  3889  	if n := numTokens(subject); n < 5 {
  3890  		s.Warnf(badAPIRequestT, msg)
  3891  		return
  3892  	} else if n == 5 {
  3893  		// Legacy ephemeral.
  3894  		rt = ccLegacyEphemeral
  3895  		streamName = streamNameFromSubject(subject)
  3896  	} else {
  3897  		// New style and durable legacy.
  3898  		if tokenAt(subject, 4) == "DURABLE" {
  3899  			rt = ccLegacyDurable
  3900  			if n != 7 {
  3901  				resp.Error = NewJSConsumerDurableNameNotInSubjectError()
  3902  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3903  				return
  3904  			}
  3905  			streamName = tokenAt(subject, 6)
  3906  			consumerName = tokenAt(subject, 7)
  3907  		} else {
  3908  			streamName = streamNameFromSubject(subject)
  3909  			consumerName = consumerNameFromSubject(subject)
  3910  			// New has optional filtered subject as part of main subject..
  3911  			if n > 6 {
  3912  				tokens := strings.Split(subject, tsep)
  3913  				filteredSubject = strings.Join(tokens[6:], tsep)
  3914  			}
  3915  		}
  3916  	}
  3917  
  3918  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  3919  		if doErr {
  3920  			resp.Error = NewJSNotEnabledForAccountError()
  3921  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3922  		}
  3923  		return
  3924  	}
  3925  
  3926  	if streamName != req.Stream {
  3927  		resp.Error = NewJSStreamMismatchError()
  3928  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3929  		return
  3930  	}
  3931  
  3932  	if consumerName != _EMPTY_ {
  3933  		// Check for path like separators in the name.
  3934  		if strings.ContainsAny(consumerName, `\/`) {
  3935  			resp.Error = NewJSConsumerNameContainsPathSeparatorsError()
  3936  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3937  			return
  3938  		}
  3939  	}
  3940  
  3941  	// Should we expect a durable name
  3942  	if rt == ccLegacyDurable {
  3943  		if numTokens(subject) < 7 {
  3944  			resp.Error = NewJSConsumerDurableNameNotInSubjectError()
  3945  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3946  			return
  3947  		}
  3948  		// Now check on requirements for durable request.
  3949  		if req.Config.Durable == _EMPTY_ {
  3950  			resp.Error = NewJSConsumerDurableNameNotSetError()
  3951  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3952  			return
  3953  		}
  3954  		if consumerName != req.Config.Durable {
  3955  			resp.Error = NewJSConsumerDurableNameNotMatchSubjectError()
  3956  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3957  			return
  3958  		}
  3959  	}
  3960  	// If new style and durable set make sure they match.
  3961  	if rt == ccNew {
  3962  		if req.Config.Durable != _EMPTY_ {
  3963  			if consumerName != req.Config.Durable {
  3964  				resp.Error = NewJSConsumerDurableNameNotMatchSubjectError()
  3965  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3966  				return
  3967  			}
  3968  		}
  3969  		// New style ephemeral so we need to honor the name.
  3970  		req.Config.Name = consumerName
  3971  	}
  3972  	// Check for legacy ephemeral mis-configuration.
  3973  	if rt == ccLegacyEphemeral && req.Config.Durable != _EMPTY_ {
  3974  		resp.Error = NewJSConsumerEphemeralWithDurableNameError()
  3975  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3976  		return
  3977  	}
  3978  
  3979  	// in case of multiple filters provided, error if new API is used.
  3980  	if filteredSubject != _EMPTY_ && len(req.Config.FilterSubjects) != 0 {
  3981  		resp.Error = NewJSConsumerMultipleFiltersNotAllowedError()
  3982  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3983  		return
  3984  	}
  3985  
  3986  	// Check for a filter subject.
  3987  	if filteredSubject != _EMPTY_ && req.Config.FilterSubject != filteredSubject {
  3988  		resp.Error = NewJSConsumerCreateFilterSubjectMismatchError()
  3989  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  3990  		return
  3991  	}
  3992  
  3993  	if isClustered && !req.Config.Direct {
  3994  		// If we are inline with client, we still may need to do a callout for consumer info
  3995  		// during this call, so place in Go routine to not block client.
  3996  		// Router and Gateway API calls already in separate context.
  3997  		if c.kind != ROUTER && c.kind != GATEWAY {
  3998  			go s.jsClusteredConsumerRequest(ci, acc, subject, reply, rmsg, req.Stream, &req.Config, req.Action)
  3999  		} else {
  4000  			s.jsClusteredConsumerRequest(ci, acc, subject, reply, rmsg, req.Stream, &req.Config, req.Action)
  4001  		}
  4002  		return
  4003  	}
  4004  
  4005  	// If we are here we are single server mode.
  4006  	if req.Config.Replicas > 1 {
  4007  		resp.Error = NewJSStreamReplicasNotSupportedError()
  4008  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4009  		return
  4010  	}
  4011  
  4012  	stream, err := acc.lookupStream(req.Stream)
  4013  	if err != nil {
  4014  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  4015  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4016  		return
  4017  	}
  4018  
  4019  	// If the consumer already exists then don't allow updating the PauseUntil, just set
  4020  	// it back to whatever the current configured value is.
  4021  	if o := stream.lookupConsumer(consumerName); o != nil {
  4022  		req.Config.PauseUntil = o.cfg.PauseUntil
  4023  	}
  4024  
  4025  	o, err := stream.addConsumerWithAction(&req.Config, req.Action)
  4026  
  4027  	if err != nil {
  4028  		if IsNatsErr(err, JSConsumerStoreFailedErrF) {
  4029  			cname := req.Config.Durable // Will be empty if ephemeral.
  4030  			s.Warnf("Consumer create failed for '%s > %s > %s': %v", acc, req.Stream, cname, err)
  4031  			err = errConsumerStoreFailed
  4032  		}
  4033  		resp.Error = NewJSConsumerCreateError(err, Unless(err))
  4034  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4035  		return
  4036  	}
  4037  	resp.ConsumerInfo = o.initialInfo()
  4038  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4039  
  4040  	if o.cfg.PauseUntil != nil && !o.cfg.PauseUntil.IsZero() && time.Now().Before(*o.cfg.PauseUntil) {
  4041  		o.sendPauseAdvisoryLocked(&o.cfg)
  4042  	}
  4043  }
  4044  
  4045  // Request for the list of all consumer names.
  4046  func (s *Server) jsConsumerNamesRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  4047  	if c == nil || !s.JetStreamEnabled() {
  4048  		return
  4049  	}
  4050  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  4051  	if err != nil {
  4052  		s.Warnf(badAPIRequestT, msg)
  4053  		return
  4054  	}
  4055  
  4056  	var resp = JSApiConsumerNamesResponse{
  4057  		ApiResponse: ApiResponse{Type: JSApiConsumerNamesResponseType},
  4058  		Consumers:   []string{},
  4059  	}
  4060  
  4061  	// Determine if we should proceed here when we are in clustered mode.
  4062  	if s.JetStreamIsClustered() {
  4063  		js, cc := s.getJetStreamCluster()
  4064  		if js == nil || cc == nil {
  4065  			return
  4066  		}
  4067  		if js.isLeaderless() {
  4068  			resp.Error = NewJSClusterNotAvailError()
  4069  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4070  			return
  4071  		}
  4072  		// Make sure we are meta leader.
  4073  		if !s.JetStreamIsLeader() {
  4074  			return
  4075  		}
  4076  	}
  4077  
  4078  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  4079  		if doErr {
  4080  			resp.Error = NewJSNotEnabledForAccountError()
  4081  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4082  		}
  4083  		return
  4084  	}
  4085  
  4086  	var offset int
  4087  	if !isEmptyRequest(msg) {
  4088  		var req JSApiConsumersRequest
  4089  		if err := json.Unmarshal(msg, &req); err != nil {
  4090  			resp.Error = NewJSInvalidJSONError()
  4091  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4092  			return
  4093  		}
  4094  		offset = req.Offset
  4095  	}
  4096  
  4097  	streamName := streamNameFromSubject(subject)
  4098  	var numConsumers int
  4099  
  4100  	if s.JetStreamIsClustered() {
  4101  		js, cc := s.getJetStreamCluster()
  4102  		if js == nil || cc == nil {
  4103  			// TODO(dlc) - Debug or Warn?
  4104  			return
  4105  		}
  4106  		js.mu.RLock()
  4107  		sas := cc.streams[acc.Name]
  4108  		if sas == nil {
  4109  			js.mu.RUnlock()
  4110  			resp.Error = NewJSStreamNotFoundError()
  4111  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4112  			return
  4113  		}
  4114  		sa := sas[streamName]
  4115  		if sa == nil || sa.err != nil {
  4116  			js.mu.RUnlock()
  4117  			resp.Error = NewJSStreamNotFoundError()
  4118  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4119  			return
  4120  		}
  4121  		for consumer := range sa.consumers {
  4122  			resp.Consumers = append(resp.Consumers, consumer)
  4123  		}
  4124  		if len(resp.Consumers) > 1 {
  4125  			sort.Slice(resp.Consumers, func(i, j int) bool { return strings.Compare(resp.Consumers[i], resp.Consumers[j]) < 0 })
  4126  		}
  4127  		numConsumers = len(resp.Consumers)
  4128  		if offset > numConsumers {
  4129  			offset = numConsumers
  4130  		}
  4131  		resp.Consumers = resp.Consumers[offset:]
  4132  		if len(resp.Consumers) > JSApiNamesLimit {
  4133  			resp.Consumers = resp.Consumers[:JSApiNamesLimit]
  4134  		}
  4135  		js.mu.RUnlock()
  4136  
  4137  	} else {
  4138  		mset, err := acc.lookupStream(streamName)
  4139  		if err != nil {
  4140  			resp.Error = NewJSStreamNotFoundError(Unless(err))
  4141  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4142  			return
  4143  		}
  4144  
  4145  		obs := mset.getPublicConsumers()
  4146  		sort.Slice(obs, func(i, j int) bool {
  4147  			return strings.Compare(obs[i].name, obs[j].name) < 0
  4148  		})
  4149  
  4150  		numConsumers = len(obs)
  4151  		if offset > numConsumers {
  4152  			offset = numConsumers
  4153  		}
  4154  
  4155  		for _, o := range obs[offset:] {
  4156  			resp.Consumers = append(resp.Consumers, o.String())
  4157  			if len(resp.Consumers) >= JSApiNamesLimit {
  4158  				break
  4159  			}
  4160  		}
  4161  	}
  4162  	resp.Total = numConsumers
  4163  	resp.Limit = JSApiNamesLimit
  4164  	resp.Offset = offset
  4165  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4166  }
  4167  
  4168  // Request for the list of all detailed consumer information.
  4169  func (s *Server) jsConsumerListRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  4170  	if c == nil || !s.JetStreamEnabled() {
  4171  		return
  4172  	}
  4173  
  4174  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  4175  	if err != nil {
  4176  		s.Warnf(badAPIRequestT, msg)
  4177  		return
  4178  	}
  4179  
  4180  	var resp = JSApiConsumerListResponse{
  4181  		ApiResponse: ApiResponse{Type: JSApiConsumerListResponseType},
  4182  		Consumers:   []*ConsumerInfo{},
  4183  	}
  4184  
  4185  	// Determine if we should proceed here when we are in clustered mode.
  4186  	if s.JetStreamIsClustered() {
  4187  		js, cc := s.getJetStreamCluster()
  4188  		if js == nil || cc == nil {
  4189  			return
  4190  		}
  4191  		if js.isLeaderless() {
  4192  			resp.Error = NewJSClusterNotAvailError()
  4193  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4194  			return
  4195  		}
  4196  		// Make sure we are meta leader.
  4197  		if !s.JetStreamIsLeader() {
  4198  			return
  4199  		}
  4200  	}
  4201  
  4202  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  4203  		if doErr {
  4204  			resp.Error = NewJSNotEnabledForAccountError()
  4205  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4206  		}
  4207  		return
  4208  	}
  4209  
  4210  	var offset int
  4211  	if !isEmptyRequest(msg) {
  4212  		var req JSApiConsumersRequest
  4213  		if err := json.Unmarshal(msg, &req); err != nil {
  4214  			resp.Error = NewJSInvalidJSONError()
  4215  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4216  			return
  4217  		}
  4218  		offset = req.Offset
  4219  	}
  4220  
  4221  	streamName := streamNameFromSubject(subject)
  4222  
  4223  	// Clustered mode will invoke a scatter and gather.
  4224  	if s.JetStreamIsClustered() {
  4225  		// Need to copy these off before sending.. don't move this inside startGoRoutine!!!
  4226  		msg = copyBytes(msg)
  4227  		s.startGoRoutine(func() {
  4228  			s.jsClusteredConsumerListRequest(acc, ci, offset, streamName, subject, reply, msg)
  4229  		})
  4230  		return
  4231  	}
  4232  
  4233  	mset, err := acc.lookupStream(streamName)
  4234  	if err != nil {
  4235  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  4236  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4237  		return
  4238  	}
  4239  
  4240  	obs := mset.getPublicConsumers()
  4241  	sort.Slice(obs, func(i, j int) bool {
  4242  		return strings.Compare(obs[i].name, obs[j].name) < 0
  4243  	})
  4244  
  4245  	ocnt := len(obs)
  4246  	if offset > ocnt {
  4247  		offset = ocnt
  4248  	}
  4249  
  4250  	for _, o := range obs[offset:] {
  4251  		if cinfo := o.info(); cinfo != nil {
  4252  			resp.Consumers = append(resp.Consumers, cinfo)
  4253  		}
  4254  		if len(resp.Consumers) >= JSApiListLimit {
  4255  			break
  4256  		}
  4257  	}
  4258  	resp.Total = ocnt
  4259  	resp.Limit = JSApiListLimit
  4260  	resp.Offset = offset
  4261  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4262  }
  4263  
  4264  // Request for information about an consumer.
  4265  func (s *Server) jsConsumerInfoRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  4266  	if c == nil || !s.JetStreamEnabled() {
  4267  		return
  4268  	}
  4269  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  4270  	if err != nil {
  4271  		s.Warnf(badAPIRequestT, msg)
  4272  		return
  4273  	}
  4274  
  4275  	streamName := streamNameFromSubject(subject)
  4276  	consumerName := consumerNameFromSubject(subject)
  4277  
  4278  	var resp = JSApiConsumerInfoResponse{ApiResponse: ApiResponse{Type: JSApiConsumerInfoResponseType}}
  4279  
  4280  	if !isEmptyRequest(msg) {
  4281  		resp.Error = NewJSNotEmptyRequestError()
  4282  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4283  		return
  4284  	}
  4285  
  4286  	// If we are in clustered mode we need to be the stream leader to proceed.
  4287  	if s.JetStreamIsClustered() {
  4288  		// Check to make sure the consumer is assigned.
  4289  		js, cc := s.getJetStreamCluster()
  4290  		if js == nil || cc == nil {
  4291  			return
  4292  		}
  4293  
  4294  		js.mu.RLock()
  4295  		isLeader, sa, ca := cc.isLeader(), js.streamAssignment(acc.Name, streamName), js.consumerAssignment(acc.Name, streamName, consumerName)
  4296  		ourID := cc.meta.ID()
  4297  		var rg *raftGroup
  4298  		var offline, isMember bool
  4299  		if ca != nil {
  4300  			if rg = ca.Group; rg != nil {
  4301  				offline = s.allPeersOffline(rg)
  4302  				isMember = rg.isMember(ourID)
  4303  			}
  4304  		}
  4305  		// Capture consumer leader here.
  4306  		isConsumerLeader := cc.isConsumerLeader(acc.Name, streamName, consumerName)
  4307  		// Also capture if we think there is no meta leader.
  4308  		var isLeaderLess bool
  4309  		if !isLeader {
  4310  			isLeaderLess = cc.meta.GroupLeader() == _EMPTY_ && time.Since(cc.meta.Created()) > lostQuorumIntervalDefault
  4311  		}
  4312  		js.mu.RUnlock()
  4313  
  4314  		if isLeader && ca == nil {
  4315  			// We can't find the consumer, so mimic what would be the errors below.
  4316  			if hasJS, doErr := acc.checkJetStream(); !hasJS {
  4317  				if doErr {
  4318  					resp.Error = NewJSNotEnabledForAccountError()
  4319  					s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4320  				}
  4321  				return
  4322  			}
  4323  			if sa == nil {
  4324  				resp.Error = NewJSStreamNotFoundError()
  4325  				s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4326  				return
  4327  			}
  4328  			// If we are here the consumer is not present.
  4329  			resp.Error = NewJSConsumerNotFoundError()
  4330  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4331  			return
  4332  		} else if ca == nil {
  4333  			if isLeaderLess {
  4334  				resp.Error = NewJSClusterNotAvailError()
  4335  				// Delaying an error response gives the leader a chance to respond before us
  4336  				s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), nil)
  4337  			}
  4338  			return
  4339  		} else if isLeader && offline {
  4340  			resp.Error = NewJSConsumerOfflineError()
  4341  			s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), nil)
  4342  			return
  4343  		}
  4344  
  4345  		// Check to see if we are a member of the group and if the group has no leader.
  4346  		if isMember && js.isGroupLeaderless(ca.Group) {
  4347  			resp.Error = NewJSClusterNotAvailError()
  4348  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4349  			return
  4350  		}
  4351  
  4352  		// We have the consumer assigned and a leader, so only the consumer leader should answer.
  4353  		if !isConsumerLeader {
  4354  			if isLeaderLess {
  4355  				resp.Error = NewJSClusterNotAvailError()
  4356  				// Delaying an error response gives the leader a chance to respond before us
  4357  				s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), ca.Group)
  4358  				return
  4359  			}
  4360  
  4361  			var node RaftNode
  4362  			var leaderNotPartOfGroup bool
  4363  
  4364  			// We have a consumer assignment.
  4365  			if isMember {
  4366  				js.mu.RLock()
  4367  				if rg.node != nil {
  4368  					node = rg.node
  4369  					if gl := node.GroupLeader(); gl != _EMPTY_ && !rg.isMember(gl) {
  4370  						leaderNotPartOfGroup = true
  4371  					}
  4372  				}
  4373  				js.mu.RUnlock()
  4374  			}
  4375  
  4376  			// Check if we should ignore all together.
  4377  			if node == nil {
  4378  				// We have been assigned but have not created a node yet. If we are a member return
  4379  				// our config and defaults for state and no cluster info.
  4380  				if isMember {
  4381  					// Since we access consumerAssignment, need js lock.
  4382  					js.mu.RLock()
  4383  					resp.ConsumerInfo = &ConsumerInfo{
  4384  						Stream:    ca.Stream,
  4385  						Name:      ca.Name,
  4386  						Created:   ca.Created,
  4387  						Config:    ca.Config,
  4388  						TimeStamp: time.Now().UTC(),
  4389  					}
  4390  					b := s.jsonResponse(resp)
  4391  					js.mu.RUnlock()
  4392  					s.sendAPIResponse(ci, acc, subject, reply, string(msg), b)
  4393  				}
  4394  				return
  4395  			}
  4396  			// If we are a member and we have a group leader or we had a previous leader consider bailing out.
  4397  			if node.GroupLeader() != _EMPTY_ || node.HadPreviousLeader() {
  4398  				if leaderNotPartOfGroup {
  4399  					resp.Error = NewJSConsumerOfflineError()
  4400  					s.sendDelayedAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp), nil)
  4401  				}
  4402  				return
  4403  			}
  4404  			// If we are here we are a member and this is just a new consumer that does not have a leader yet.
  4405  			// Will fall through and return what we have. All consumers can respond but this should be very rare
  4406  			// but makes more sense to clients when they try to create, get a consumer exists, and then do consumer info.
  4407  		}
  4408  	}
  4409  
  4410  	if !acc.JetStreamEnabled() {
  4411  		resp.Error = NewJSNotEnabledForAccountError()
  4412  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4413  		return
  4414  	}
  4415  
  4416  	mset, err := acc.lookupStream(streamName)
  4417  	if err != nil {
  4418  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  4419  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4420  		return
  4421  	}
  4422  
  4423  	obs := mset.lookupConsumer(consumerName)
  4424  	if obs == nil {
  4425  		resp.Error = NewJSConsumerNotFoundError()
  4426  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4427  		return
  4428  	}
  4429  
  4430  	if resp.ConsumerInfo = obs.info(); resp.ConsumerInfo == nil {
  4431  		// This consumer returned nil which means it's closed. Respond with not found.
  4432  		resp.Error = NewJSConsumerNotFoundError()
  4433  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4434  		return
  4435  	}
  4436  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4437  }
  4438  
  4439  // Request to delete an Consumer.
  4440  func (s *Server) jsConsumerDeleteRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  4441  	if c == nil || !s.JetStreamEnabled() {
  4442  		return
  4443  	}
  4444  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  4445  	if err != nil {
  4446  		s.Warnf(badAPIRequestT, msg)
  4447  		return
  4448  	}
  4449  
  4450  	var resp = JSApiConsumerDeleteResponse{ApiResponse: ApiResponse{Type: JSApiConsumerDeleteResponseType}}
  4451  
  4452  	// Determine if we should proceed here when we are in clustered mode.
  4453  	if s.JetStreamIsClustered() {
  4454  		js, cc := s.getJetStreamCluster()
  4455  		if js == nil || cc == nil {
  4456  			return
  4457  		}
  4458  		if js.isLeaderless() {
  4459  			resp.Error = NewJSClusterNotAvailError()
  4460  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4461  			return
  4462  		}
  4463  		// Make sure we are meta leader.
  4464  		if !s.JetStreamIsLeader() {
  4465  			return
  4466  		}
  4467  	}
  4468  
  4469  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  4470  		if doErr {
  4471  			resp.Error = NewJSNotEnabledForAccountError()
  4472  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4473  		}
  4474  		return
  4475  	}
  4476  	if !isEmptyRequest(msg) {
  4477  		resp.Error = NewJSNotEmptyRequestError()
  4478  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4479  		return
  4480  	}
  4481  	stream := streamNameFromSubject(subject)
  4482  	consumer := consumerNameFromSubject(subject)
  4483  
  4484  	if s.JetStreamIsClustered() {
  4485  		s.jsClusteredConsumerDeleteRequest(ci, acc, stream, consumer, subject, reply, rmsg)
  4486  		return
  4487  	}
  4488  
  4489  	mset, err := acc.lookupStream(stream)
  4490  	if err != nil {
  4491  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  4492  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4493  		return
  4494  	}
  4495  
  4496  	obs := mset.lookupConsumer(consumer)
  4497  	if obs == nil {
  4498  		resp.Error = NewJSConsumerNotFoundError()
  4499  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4500  		return
  4501  	}
  4502  	if err := obs.delete(); err != nil {
  4503  		resp.Error = NewJSStreamGeneralError(err, Unless(err))
  4504  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4505  		return
  4506  	}
  4507  	resp.Success = true
  4508  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4509  }
  4510  
  4511  // Request to pause or unpause a Consumer.
  4512  func (s *Server) jsConsumerPauseRequest(sub *subscription, c *client, _ *Account, subject, reply string, rmsg []byte) {
  4513  	if c == nil || !s.JetStreamEnabled() {
  4514  		return
  4515  	}
  4516  	ci, acc, _, msg, err := s.getRequestInfo(c, rmsg)
  4517  	if err != nil {
  4518  		s.Warnf(badAPIRequestT, msg)
  4519  		return
  4520  	}
  4521  
  4522  	var req JSApiConsumerPauseRequest
  4523  	var resp = JSApiConsumerPauseResponse{ApiResponse: ApiResponse{Type: JSApiConsumerPauseResponseType}}
  4524  
  4525  	if !isEmptyRequest(msg) {
  4526  		if err := json.Unmarshal(msg, &req); err != nil {
  4527  			resp.Error = NewJSInvalidJSONError()
  4528  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4529  			return
  4530  		}
  4531  	}
  4532  
  4533  	// Determine if we should proceed here when we are in clustered mode.
  4534  	isClustered := s.JetStreamIsClustered()
  4535  	js, cc := s.getJetStreamCluster()
  4536  	if isClustered {
  4537  		if js == nil || cc == nil {
  4538  			return
  4539  		}
  4540  		if js.isLeaderless() {
  4541  			resp.Error = NewJSClusterNotAvailError()
  4542  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4543  			return
  4544  		}
  4545  		// Make sure we are meta leader.
  4546  		if !s.JetStreamIsLeader() {
  4547  			return
  4548  		}
  4549  	}
  4550  
  4551  	if hasJS, doErr := acc.checkJetStream(); !hasJS {
  4552  		if doErr {
  4553  			resp.Error = NewJSNotEnabledForAccountError()
  4554  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4555  		}
  4556  		return
  4557  	}
  4558  
  4559  	stream := streamNameFromSubject(subject)
  4560  	consumer := consumerNameFromSubject(subject)
  4561  
  4562  	if isClustered {
  4563  		sa := js.streamAssignment(acc.Name, stream)
  4564  		if sa == nil {
  4565  			resp.Error = NewJSStreamNotFoundError(Unless(err))
  4566  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4567  			return
  4568  		}
  4569  
  4570  		ca, ok := sa.consumers[consumer]
  4571  		if !ok || ca == nil {
  4572  			resp.Error = NewJSConsumerNotFoundError()
  4573  			s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4574  			return
  4575  		}
  4576  
  4577  		nca := *ca
  4578  		pauseUTC := req.PauseUntil.UTC()
  4579  		if !pauseUTC.IsZero() {
  4580  			nca.Config.PauseUntil = &pauseUTC
  4581  		}
  4582  		eca := encodeAddConsumerAssignment(&nca)
  4583  		cc.meta.Propose(eca)
  4584  
  4585  		resp.PauseUntil = pauseUTC
  4586  		if resp.Paused = time.Now().Before(pauseUTC); resp.Paused {
  4587  			resp.PauseRemaining = time.Until(pauseUTC)
  4588  		}
  4589  		s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4590  		return
  4591  	}
  4592  
  4593  	mset, err := acc.lookupStream(stream)
  4594  	if err != nil {
  4595  		resp.Error = NewJSStreamNotFoundError(Unless(err))
  4596  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4597  		return
  4598  	}
  4599  
  4600  	obs := mset.lookupConsumer(consumer)
  4601  	if obs == nil {
  4602  		resp.Error = NewJSConsumerNotFoundError()
  4603  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4604  		return
  4605  	}
  4606  
  4607  	ncfg := obs.cfg
  4608  	pauseUTC := req.PauseUntil.UTC()
  4609  	if !pauseUTC.IsZero() {
  4610  		ncfg.PauseUntil = &pauseUTC
  4611  	} else {
  4612  		ncfg.PauseUntil = nil
  4613  	}
  4614  
  4615  	if err := obs.updateConfig(&ncfg); err != nil {
  4616  		// The only type of error that should be returned here is from o.store,
  4617  		// so use a store failed error type.
  4618  		resp.Error = NewJSConsumerStoreFailedError(err)
  4619  		s.sendAPIErrResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(&resp))
  4620  		return
  4621  	}
  4622  
  4623  	resp.PauseUntil = pauseUTC
  4624  	if resp.Paused = time.Now().Before(pauseUTC); resp.Paused {
  4625  		resp.PauseRemaining = time.Until(pauseUTC)
  4626  	}
  4627  	s.sendAPIResponse(ci, acc, subject, reply, string(msg), s.jsonResponse(resp))
  4628  }
  4629  
  4630  // sendJetStreamAPIAuditAdvisor will send the audit event for a given event.
  4631  func (s *Server) sendJetStreamAPIAuditAdvisory(ci *ClientInfo, acc *Account, subject, request, response string) {
  4632  	s.publishAdvisory(acc, JSAuditAdvisory, JSAPIAudit{
  4633  		TypedEvent: TypedEvent{
  4634  			Type: JSAPIAuditType,
  4635  			ID:   nuid.Next(),
  4636  			Time: time.Now().UTC(),
  4637  		},
  4638  		Server:   s.Name(),
  4639  		Client:   ci,
  4640  		Subject:  subject,
  4641  		Request:  request,
  4642  		Response: response,
  4643  		Domain:   s.getOpts().JetStreamDomain,
  4644  	})
  4645  }