github.com/wtsi-ssg/wrstat/v3@v3.2.3/server/server.go (about)

     1  /*******************************************************************************
     2   * Copyright (c) 2022 Genome Research Ltd.
     3   *
     4   * Authors:
     5   *	- Sendu Bala <sb10@sanger.ac.uk>
     6   *
     7   * Permission is hereby granted, free of charge, to any person obtaining
     8   * a copy of this software and associated documentation files (the
     9   * "Software"), to deal in the Software without restriction, including
    10   * without limitation the rights to use, copy, modify, merge, publish,
    11   * distribute, sublicense, and/or sell copies of the Software, and to
    12   * permit persons to whom the Software is furnished to do so, subject to
    13   * the following conditions:
    14   *
    15   * The above copyright notice and this permission notice shall be included
    16   * in all copies or substantial portions of the Software.
    17   *
    18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    19   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    20   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    21   * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    22   * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    23   * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    24   * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    25   ******************************************************************************/
    26  
    27  // package server provides a web server for a REST API and website.
    28  
    29  package server
    30  
    31  import (
    32  	"embed"
    33  	"io"
    34  	"sync"
    35  	"time"
    36  
    37  	gas "github.com/wtsi-hgi/go-authserver"
    38  	"github.com/wtsi-ssg/wrstat/v3/dgut"
    39  	"github.com/wtsi-ssg/wrstat/v3/watch"
    40  )
    41  
    42  //go:embed static
    43  var staticFS embed.FS
    44  
    45  const (
    46  	wherePath = "/where"
    47  
    48  	// EndPointWhere is the endpoint for making where queries if authorization
    49  	// isn't implemented.
    50  	EndPointWhere = gas.EndPointREST + wherePath
    51  
    52  	// EndPointAuthWhere is the endpoint for making where queries if
    53  	// authorization is implemented.
    54  	EndPointAuthWhere = gas.EndPointAuth + wherePath
    55  
    56  	groupAreasPaths = "/group-areas"
    57  
    58  	// EndPointAuthGroupAreas is the endpoint for making queries on what the
    59  	// group areas are, which is available if authorization is implemented.
    60  	EndPointAuthGroupAreas = gas.EndPointAuth + groupAreasPaths
    61  
    62  	// TreePath is the path to the static tree website.
    63  	TreePath = "/tree"
    64  
    65  	// EndPointAuthTree is the endpoint for making treemap queries when
    66  	// authorization is implemented.
    67  	EndPointAuthTree = gas.EndPointAuth + TreePath
    68  
    69  	defaultDir    = "/"
    70  	defaultSplits = "2"
    71  	unknown       = "#unknown"
    72  )
    73  
    74  // Server is used to start a web server that provides a REST API to the dgut
    75  // package's database, and a website that displays the information nicely.
    76  type Server struct {
    77  	gas.Server
    78  	tree           *dgut.Tree
    79  	treeMutex      sync.RWMutex
    80  	whiteCB        WhiteListCallback
    81  	uidToNameCache map[uint32]string
    82  	gidToNameCache map[uint32]string
    83  	userToGIDs     map[string][]string
    84  	dgutPaths      []string
    85  	dgutWatcher    *watch.Watcher
    86  	dataTimeStamp  time.Time
    87  	areas          map[string][]string
    88  }
    89  
    90  // New creates a Server which can serve a REST API and website.
    91  //
    92  // It logs to the given io.Writer, which could for example be syslog using the
    93  // log/syslog pkg with syslog.new(syslog.LOG_INFO, "tag").
    94  func New(logWriter io.Writer) *Server {
    95  	s := &Server{
    96  		Server:         *gas.New(logWriter),
    97  		uidToNameCache: make(map[uint32]string),
    98  		gidToNameCache: make(map[uint32]string),
    99  		userToGIDs:     make(map[string][]string),
   100  	}
   101  
   102  	s.SetStopCallBack(s.stop)
   103  
   104  	return s
   105  }
   106  
   107  // stop is called when the server is Stop()ped, cleaning up our additional
   108  // properties.
   109  func (s *Server) stop() {
   110  	s.treeMutex.Lock()
   111  	defer s.treeMutex.Unlock()
   112  
   113  	if s.dgutWatcher != nil {
   114  		s.dgutWatcher.Stop()
   115  		s.dgutWatcher = nil
   116  	}
   117  
   118  	if s.tree != nil {
   119  		s.tree.Close()
   120  		s.tree = nil
   121  	}
   122  }