/* CreateDocument - Creates a fresh Binder for a new document, which is subsequently stored, returns an error if either the document ID is already currently in use, or if there is a problem storing the new document. May require authentication, if so a userID is supplied. */ func (c *impl) CreateDocument( userID, token string, doc store.Document, timeout time.Duration, ) (binder.Portal, error) { c.log.Debugf("Creating new document with userID %v token %v\n", userID, token) if c.auth.Authenticate(userID, token, "") < acl.CreateAccess { c.stats.Incr("curator.create.rejected_client", 1) return nil, fmt.Errorf("failed to gain permission to create with token: %v\n", token) } c.stats.Incr("curator.create.accepted_client", 1) // Always generate a fresh ID doc.ID = util.GenerateStampedUUID() if err := c.store.Create(doc); err != nil { c.stats.Incr("curator.create_new.failed", 1) c.log.Errorf("Failed to create new document: %v\n", err) return nil, err } openBinder, err := binder.New( doc.ID, c.store, c.config.BinderConfig, c.errorChan, c.log, c.stats, ) if err != nil { c.stats.Incr("curator.bind_new.failed", 1) c.log.Errorf("Failed to bind to new document: %v\n", err) return nil, err } c.binderMutex.Lock() c.openBinders[doc.ID] = openBinder c.binderMutex.Unlock() c.stats.Incr("curator.open_binders", 1) return openBinder.Subscribe(userID, timeout) }
/* ReadDocument - Locates or creates a Binder for an existing document and returns that Binder for subscribing to with read only privileges. Returns an error if there was a problem locating the document. */ func (c *impl) ReadDocument( userID, token, documentID string, timeout time.Duration, ) (binder.Portal, error) { c.log.Debugf("finding document %v, with userID %v token %v\n", documentID, userID, token) if c.auth.Authenticate(userID, token, documentID) < acl.ReadAccess { c.stats.Incr("curator.read.rejected_client", 1) return nil, fmt.Errorf( "failed to authorise read only join of document id: %v with token: %v\n", documentID, token, ) } c.stats.Incr("curator.read.accepted_client", 1) c.binderMutex.Lock() // Check for existing binder if openBinder, ok := c.openBinders[documentID]; ok { c.binderMutex.Unlock() return openBinder.SubscribeReadOnly(userID, timeout) } openBinder, err := binder.New( documentID, c.store, c.config.BinderConfig, c.errorChan, c.log, c.stats, ) if err != nil { c.binderMutex.Unlock() c.stats.Incr("curator.bind_existing.failed", 1) c.log.Errorf("Failed to bind to document %v: %v\n", documentID, err) return nil, err } c.openBinders[documentID] = openBinder c.binderMutex.Unlock() c.stats.Incr("curator.open_binders", 1) return openBinder.SubscribeReadOnly(userID, timeout) }