github.com/cs3org/reva/v2@v2.27.7/internal/http/services/mentix/mentix.go (about) 1 // Copyright 2018-2021 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 mentix 20 21 import ( 22 "net/http" 23 24 "github.com/cs3org/reva/v2/pkg/mentix/meshdata" 25 "github.com/mitchellh/mapstructure" 26 "github.com/pkg/errors" 27 "github.com/rs/zerolog" 28 29 "github.com/cs3org/reva/v2/pkg/mentix" 30 "github.com/cs3org/reva/v2/pkg/mentix/config" 31 "github.com/cs3org/reva/v2/pkg/mentix/exchangers" 32 "github.com/cs3org/reva/v2/pkg/rhttp/global" 33 ) 34 35 func init() { 36 global.Register(serviceName, New) 37 } 38 39 type svc struct { 40 conf *config.Configuration 41 mntx *mentix.Mentix 42 log *zerolog.Logger 43 44 stopSignal chan struct{} 45 } 46 47 const ( 48 serviceName = "mentix" 49 ) 50 51 func (s *svc) Close() error { 52 // Trigger and close the stopSignal signal channel to stop Mentix 53 s.stopSignal <- struct{}{} 54 close(s.stopSignal) 55 56 return nil 57 } 58 59 func (s *svc) Prefix() string { 60 return s.conf.Prefix 61 } 62 63 func (s *svc) Unprotected() []string { 64 // Get all endpoints exposed by the RequestExchangers 65 importers := s.mntx.GetRequestImporters() 66 exporters := s.mntx.GetRequestExporters() 67 68 getEndpoints := func(exchangers []exchangers.RequestExchanger) []string { 69 endpoints := make([]string, 0, len(exchangers)) 70 for _, exchanger := range exchangers { 71 if !exchanger.IsProtectedEndpoint() { 72 endpoints = append(endpoints, exchanger.Endpoint()) 73 } 74 } 75 return endpoints 76 } 77 78 endpoints := make([]string, 0, len(importers)+len(exporters)) 79 endpoints = append(endpoints, getEndpoints(importers)...) 80 endpoints = append(endpoints, getEndpoints(exporters)...) 81 82 return endpoints 83 } 84 85 func (s *svc) Handler() http.Handler { 86 // Forward requests to Mentix 87 return http.HandlerFunc(s.mntx.RequestHandler) 88 } 89 90 func (s *svc) startBackgroundService() { 91 // Just run Mentix in the background 92 go func() { 93 if err := s.mntx.Run(s.stopSignal); err != nil { 94 s.log.Err(err).Msg("error while running mentix") 95 } 96 }() 97 } 98 99 func parseConfig(m map[string]interface{}) (*config.Configuration, error) { 100 cfg := &config.Configuration{} 101 if err := mapstructure.Decode(m, &cfg); err != nil { 102 return nil, errors.Wrap(err, "mentix: error decoding configuration") 103 } 104 applyInternalConfig(m, cfg) 105 applyDefaultConfig(cfg) 106 return cfg, nil 107 } 108 109 func applyInternalConfig(m map[string]interface{}, conf *config.Configuration) { 110 getSubsections := func(section string) []string { 111 subsections := make([]string, 0, 5) 112 if list, ok := m[section].(map[string]interface{}); ok { 113 for name := range list { 114 subsections = append(subsections, name) 115 } 116 } 117 return subsections 118 } 119 120 conf.EnabledConnectors = getSubsections("connectors") 121 conf.EnabledImporters = getSubsections("importers") 122 conf.EnabledExporters = getSubsections("exporters") 123 } 124 125 func applyDefaultConfig(conf *config.Configuration) { 126 // General 127 if conf.Prefix == "" { 128 conf.Prefix = serviceName 129 } 130 131 if conf.UpdateInterval == "" { 132 conf.UpdateInterval = "1h" // Update once per hour 133 } 134 135 // Connectors 136 if conf.Connectors.GOCDB.Scope == "" { 137 conf.Connectors.GOCDB.Scope = "SM" // TODO(Daniel-WWU-IT): This might change in the future 138 } 139 140 // Exporters 141 addDefaultConnector := func(enabledList *[]string) { 142 if len(*enabledList) == 0 { 143 *enabledList = append(*enabledList, "*") 144 } 145 } 146 147 if conf.Exporters.WebAPI.Endpoint == "" { 148 conf.Exporters.WebAPI.Endpoint = "/sites" 149 } 150 addDefaultConnector(&conf.Exporters.WebAPI.EnabledConnectors) 151 152 if conf.Exporters.CS3API.Endpoint == "" { 153 conf.Exporters.CS3API.Endpoint = "/cs3" 154 } 155 addDefaultConnector(&conf.Exporters.CS3API.EnabledConnectors) 156 if len(conf.Exporters.CS3API.ElevatedServiceTypes) == 0 { 157 conf.Exporters.CS3API.ElevatedServiceTypes = append(conf.Exporters.CS3API.ElevatedServiceTypes, meshdata.EndpointGateway, meshdata.EndpointOCM, meshdata.EndpointWebdav) 158 } 159 160 if conf.Exporters.SiteLocations.Endpoint == "" { 161 conf.Exporters.SiteLocations.Endpoint = "/loc" 162 } 163 addDefaultConnector(&conf.Exporters.SiteLocations.EnabledConnectors) 164 165 addDefaultConnector(&conf.Exporters.PrometheusSD.EnabledConnectors) 166 addDefaultConnector(&conf.Exporters.Metrics.EnabledConnectors) 167 } 168 169 // New returns a new Mentix service. 170 func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) { 171 // Prepare the configuration 172 conf, err := parseConfig(m) 173 if err != nil { 174 return nil, err 175 } 176 177 conf.Init() 178 179 // Create the Mentix instance 180 mntx, err := mentix.New(conf, log) 181 if err != nil { 182 return nil, errors.Wrap(err, "mentix: error creating Mentix") 183 } 184 185 // Create the service and start its background activity 186 s := &svc{ 187 conf: conf, 188 mntx: mntx, 189 log: log, 190 stopSignal: make(chan struct{}), 191 } 192 s.startBackgroundService() 193 return s, nil 194 }