github.com/cs3org/reva/v2@v2.27.7/pkg/storage/fs/posix/tree/gpfswatchfolderwatcher.go (about)

     1  // Copyright 2018-2024 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package tree
    20  
    21  import (
    22  	"context"
    23  	"encoding/json"
    24  	"log"
    25  	"strconv"
    26  	"strings"
    27  
    28  	"github.com/rs/zerolog"
    29  	kafka "github.com/segmentio/kafka-go"
    30  )
    31  
    32  type GpfsWatchFolderWatcher struct {
    33  	tree    *Tree
    34  	brokers []string
    35  	log     *zerolog.Logger
    36  }
    37  
    38  func NewGpfsWatchFolderWatcher(tree *Tree, kafkaBrokers []string, log *zerolog.Logger) (*GpfsWatchFolderWatcher, error) {
    39  	return &GpfsWatchFolderWatcher{
    40  		tree:    tree,
    41  		brokers: kafkaBrokers,
    42  		log:     log,
    43  	}, nil
    44  }
    45  
    46  func (w *GpfsWatchFolderWatcher) Watch(topic string) {
    47  	r := kafka.NewReader(kafka.ReaderConfig{
    48  		Brokers: w.brokers,
    49  		GroupID: "ocis-posixfs",
    50  		Topic:   topic,
    51  	})
    52  
    53  	for {
    54  		m, err := r.ReadMessage(context.Background())
    55  		if err != nil {
    56  			break
    57  		}
    58  
    59  		lwev := &lwe{}
    60  		err = json.Unmarshal(m.Value, lwev)
    61  		if err != nil {
    62  			continue
    63  		}
    64  
    65  		if isLockFile(lwev.Path) || isTrash(lwev.Path) || w.tree.isUpload(lwev.Path) {
    66  			continue
    67  		}
    68  
    69  		go func() {
    70  			isDir := strings.Contains(lwev.Event, "IN_ISDIR")
    71  
    72  			var err error
    73  			switch {
    74  			case strings.Contains(lwev.Event, "IN_DELETE"):
    75  				err = w.tree.Scan(lwev.Path, ActionDelete, isDir)
    76  
    77  			case strings.Contains(lwev.Event, "IN_MOVE_FROM"):
    78  				err = w.tree.Scan(lwev.Path, ActionMoveFrom, isDir)
    79  
    80  			case strings.Contains(lwev.Event, "IN_CREATE"):
    81  				err = w.tree.Scan(lwev.Path, ActionCreate, isDir)
    82  
    83  			case strings.Contains(lwev.Event, "IN_CLOSE_WRITE"):
    84  				bytesWritten, convErr := strconv.Atoi(lwev.BytesWritten)
    85  				if convErr == nil && bytesWritten > 0 {
    86  					err = w.tree.Scan(lwev.Path, ActionUpdate, isDir)
    87  				}
    88  			case strings.Contains(lwev.Event, "IN_MOVED_TO"):
    89  				err = w.tree.Scan(lwev.Path, ActionMove, isDir)
    90  			}
    91  			if err != nil {
    92  				w.log.Error().Err(err).Str("path", lwev.Path).Msg("error scanning path")
    93  			}
    94  		}()
    95  	}
    96  	if err := r.Close(); err != nil {
    97  		log.Fatal("failed to close reader:", err)
    98  	}
    99  }