github.com/weaviate/weaviate@v1.24.6/adapters/handlers/rest/handlers_schema.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package rest 13 14 import ( 15 "github.com/go-openapi/runtime/middleware" 16 "github.com/sirupsen/logrus" 17 "github.com/weaviate/weaviate/adapters/handlers/rest/operations" 18 "github.com/weaviate/weaviate/adapters/handlers/rest/operations/schema" 19 "github.com/weaviate/weaviate/entities/models" 20 "github.com/weaviate/weaviate/usecases/auth/authorization/errors" 21 "github.com/weaviate/weaviate/usecases/monitoring" 22 uco "github.com/weaviate/weaviate/usecases/objects" 23 schemaUC "github.com/weaviate/weaviate/usecases/schema" 24 ) 25 26 type schemaHandlers struct { 27 manager *schemaUC.Manager 28 metricRequestsTotal restApiRequestsTotal 29 } 30 31 func (s *schemaHandlers) addClass(params schema.SchemaObjectsCreateParams, 32 principal *models.Principal, 33 ) middleware.Responder { 34 err := s.manager.AddClass(params.HTTPRequest.Context(), principal, params.ObjectClass) 35 if err != nil { 36 s.metricRequestsTotal.logError(params.ObjectClass.Class, err) 37 switch err.(type) { 38 case errors.Forbidden: 39 return schema.NewSchemaObjectsCreateForbidden(). 40 WithPayload(errPayloadFromSingleErr(err)) 41 default: 42 return schema.NewSchemaObjectsCreateUnprocessableEntity(). 43 WithPayload(errPayloadFromSingleErr(err)) 44 } 45 } 46 47 s.metricRequestsTotal.logOk(params.ObjectClass.Class) 48 return schema.NewSchemaObjectsCreateOK().WithPayload(params.ObjectClass) 49 } 50 51 func (s *schemaHandlers) updateClass(params schema.SchemaObjectsUpdateParams, 52 principal *models.Principal, 53 ) middleware.Responder { 54 err := s.manager.UpdateClass(params.HTTPRequest.Context(), principal, params.ClassName, 55 params.ObjectClass) 56 if err != nil { 57 s.metricRequestsTotal.logError(params.ClassName, err) 58 if err == schemaUC.ErrNotFound { 59 return schema.NewSchemaObjectsUpdateNotFound() 60 } 61 62 switch err.(type) { 63 case errors.Forbidden: 64 return schema.NewSchemaObjectsUpdateForbidden(). 65 WithPayload(errPayloadFromSingleErr(err)) 66 default: 67 return schema.NewSchemaObjectsUpdateUnprocessableEntity(). 68 WithPayload(errPayloadFromSingleErr(err)) 69 } 70 } 71 72 s.metricRequestsTotal.logOk(params.ClassName) 73 return schema.NewSchemaObjectsUpdateOK().WithPayload(params.ObjectClass) 74 } 75 76 func (s *schemaHandlers) getClass(params schema.SchemaObjectsGetParams, 77 principal *models.Principal, 78 ) middleware.Responder { 79 class, err := s.manager.GetClass(params.HTTPRequest.Context(), principal, params.ClassName) 80 if err != nil { 81 s.metricRequestsTotal.logError(params.ClassName, err) 82 switch err.(type) { 83 case errors.Forbidden: 84 return schema.NewSchemaObjectsGetForbidden(). 85 WithPayload(errPayloadFromSingleErr(err)) 86 default: 87 return schema.NewSchemaObjectsGetInternalServerError(). 88 WithPayload(errPayloadFromSingleErr(err)) 89 } 90 } 91 92 if class == nil { 93 s.metricRequestsTotal.logUserError(params.ClassName) 94 return schema.NewSchemaObjectsGetNotFound() 95 } 96 97 s.metricRequestsTotal.logOk(params.ClassName) 98 return schema.NewSchemaObjectsGetOK().WithPayload(class) 99 } 100 101 func (s *schemaHandlers) deleteClass(params schema.SchemaObjectsDeleteParams, principal *models.Principal) middleware.Responder { 102 err := s.manager.DeleteClass(params.HTTPRequest.Context(), principal, params.ClassName) 103 if err != nil { 104 s.metricRequestsTotal.logError(params.ClassName, err) 105 switch err.(type) { 106 case errors.Forbidden: 107 return schema.NewSchemaObjectsDeleteForbidden(). 108 WithPayload(errPayloadFromSingleErr(err)) 109 default: 110 return schema.NewSchemaObjectsDeleteBadRequest().WithPayload(errPayloadFromSingleErr(err)) 111 } 112 } 113 114 s.metricRequestsTotal.logOk(params.ClassName) 115 return schema.NewSchemaObjectsDeleteOK() 116 } 117 118 func (s *schemaHandlers) addClassProperty(params schema.SchemaObjectsPropertiesAddParams, 119 principal *models.Principal, 120 ) middleware.Responder { 121 err := s.manager.AddClassProperty(params.HTTPRequest.Context(), principal, params.ClassName, params.Body) 122 if err != nil { 123 s.metricRequestsTotal.logError(params.ClassName, err) 124 switch err.(type) { 125 case errors.Forbidden: 126 return schema.NewSchemaObjectsPropertiesAddForbidden(). 127 WithPayload(errPayloadFromSingleErr(err)) 128 default: 129 return schema.NewSchemaObjectsPropertiesAddUnprocessableEntity(). 130 WithPayload(errPayloadFromSingleErr(err)) 131 } 132 } 133 134 s.metricRequestsTotal.logOk(params.ClassName) 135 return schema.NewSchemaObjectsPropertiesAddOK().WithPayload(params.Body) 136 } 137 138 func (s *schemaHandlers) getSchema(params schema.SchemaDumpParams, principal *models.Principal) middleware.Responder { 139 dbSchema, err := s.manager.GetSchema(principal) 140 if err != nil { 141 s.metricRequestsTotal.logError("", err) 142 switch err.(type) { 143 case errors.Forbidden: 144 return schema.NewSchemaDumpForbidden(). 145 WithPayload(errPayloadFromSingleErr(err)) 146 default: 147 return schema.NewSchemaDumpForbidden().WithPayload(errPayloadFromSingleErr(err)) 148 } 149 } 150 151 payload := dbSchema.Objects 152 153 s.metricRequestsTotal.logOk("") 154 return schema.NewSchemaDumpOK().WithPayload(payload) 155 } 156 157 func (s *schemaHandlers) getClusterStatus(params schema.SchemaClusterStatusParams, principal *models.Principal) middleware.Responder { 158 status, err := s.manager.ClusterStatus(params.HTTPRequest.Context()) 159 if err == nil { 160 s.metricRequestsTotal.logOk("") 161 return schema.NewSchemaClusterStatusOK().WithPayload(status) 162 } else { 163 s.metricRequestsTotal.logServerError("", err) 164 return schema.NewSchemaClusterStatusInternalServerError().WithPayload(status) 165 } 166 } 167 168 func (s *schemaHandlers) getShardsStatus(params schema.SchemaObjectsShardsGetParams, 169 principal *models.Principal, 170 ) middleware.Responder { 171 var tenant string 172 if params.Tenant == nil { 173 tenant = "" 174 } else { 175 tenant = *params.Tenant 176 } 177 status, err := s.manager.GetShardsStatus(params.HTTPRequest.Context(), principal, params.ClassName, tenant) 178 if err != nil { 179 s.metricRequestsTotal.logError("", err) 180 switch err.(type) { 181 case errors.Forbidden: 182 return schema.NewSchemaObjectsShardsGetForbidden(). 183 WithPayload(errPayloadFromSingleErr(err)) 184 default: 185 return schema.NewSchemaObjectsShardsGetNotFound(). 186 WithPayload(errPayloadFromSingleErr(err)) 187 } 188 } 189 190 payload := status 191 192 s.metricRequestsTotal.logOk("") 193 return schema.NewSchemaObjectsShardsGetOK().WithPayload(payload) 194 } 195 196 func (s *schemaHandlers) updateShardStatus(params schema.SchemaObjectsShardsUpdateParams, 197 principal *models.Principal, 198 ) middleware.Responder { 199 err := s.manager.UpdateShardStatus( 200 params.HTTPRequest.Context(), principal, params.ClassName, params.ShardName, params.Body.Status) 201 if err != nil { 202 s.metricRequestsTotal.logError("", err) 203 switch err.(type) { 204 case errors.Forbidden: 205 return schema.NewSchemaObjectsShardsGetForbidden(). 206 WithPayload(errPayloadFromSingleErr(err)) 207 default: 208 return schema.NewSchemaObjectsShardsUpdateUnprocessableEntity(). 209 WithPayload(errPayloadFromSingleErr(err)) 210 } 211 } 212 213 payload := params.Body 214 215 s.metricRequestsTotal.logOk("") 216 return schema.NewSchemaObjectsShardsUpdateOK().WithPayload(payload) 217 } 218 219 func (s *schemaHandlers) createTenants(params schema.TenantsCreateParams, 220 principal *models.Principal, 221 ) middleware.Responder { 222 created, err := s.manager.AddTenants( 223 params.HTTPRequest.Context(), principal, params.ClassName, params.Body) 224 if err != nil { 225 s.metricRequestsTotal.logError(params.ClassName, err) 226 switch err.(type) { 227 case errors.Forbidden: 228 return schema.NewTenantsCreateForbidden(). 229 WithPayload(errPayloadFromSingleErr(err)) 230 default: 231 return schema.NewTenantsCreateUnprocessableEntity(). 232 WithPayload(errPayloadFromSingleErr(err)) 233 } 234 } 235 236 s.metricRequestsTotal.logOk(params.ClassName) 237 return schema.NewTenantsCreateOK().WithPayload(created) 238 } 239 240 func (s *schemaHandlers) updateTenants(params schema.TenantsUpdateParams, 241 principal *models.Principal, 242 ) middleware.Responder { 243 err := s.manager.UpdateTenants( 244 params.HTTPRequest.Context(), principal, params.ClassName, params.Body) 245 if err != nil { 246 s.metricRequestsTotal.logError(params.ClassName, err) 247 switch err.(type) { 248 case errors.Forbidden: 249 return schema.NewTenantsUpdateForbidden(). 250 WithPayload(errPayloadFromSingleErr(err)) 251 default: 252 return schema.NewTenantsUpdateUnprocessableEntity(). 253 WithPayload(errPayloadFromSingleErr(err)) 254 } 255 } 256 257 payload := params.Body 258 259 s.metricRequestsTotal.logOk(params.ClassName) 260 return schema.NewTenantsUpdateOK().WithPayload(payload) 261 } 262 263 func (s *schemaHandlers) deleteTenants(params schema.TenantsDeleteParams, 264 principal *models.Principal, 265 ) middleware.Responder { 266 err := s.manager.DeleteTenants( 267 params.HTTPRequest.Context(), principal, params.ClassName, params.Tenants) 268 if err != nil { 269 s.metricRequestsTotal.logError(params.ClassName, err) 270 switch err.(type) { 271 case errors.Forbidden: 272 return schema.NewTenantsDeleteForbidden(). 273 WithPayload(errPayloadFromSingleErr(err)) 274 default: 275 return schema.NewTenantsDeleteUnprocessableEntity(). 276 WithPayload(errPayloadFromSingleErr(err)) 277 } 278 } 279 280 s.metricRequestsTotal.logOk(params.ClassName) 281 return schema.NewTenantsDeleteOK() 282 } 283 284 func (s *schemaHandlers) getTenants(params schema.TenantsGetParams, 285 principal *models.Principal, 286 ) middleware.Responder { 287 tenants, err := s.manager.GetTenants(params.HTTPRequest.Context(), principal, params.ClassName) 288 if err != nil { 289 s.metricRequestsTotal.logError(params.ClassName, err) 290 switch err.(type) { 291 case errors.Forbidden: 292 return schema.NewTenantsGetForbidden(). 293 WithPayload(errPayloadFromSingleErr(err)) 294 default: 295 return schema.NewTenantsGetUnprocessableEntity(). 296 WithPayload(errPayloadFromSingleErr(err)) 297 } 298 } 299 300 s.metricRequestsTotal.logOk(params.ClassName) 301 return schema.NewTenantsGetOK().WithPayload(tenants) 302 } 303 304 func setupSchemaHandlers(api *operations.WeaviateAPI, manager *schemaUC.Manager, metrics *monitoring.PrometheusMetrics, logger logrus.FieldLogger) { 305 h := &schemaHandlers{manager, newSchemaRequestsTotal(metrics, logger)} 306 307 api.SchemaSchemaObjectsCreateHandler = schema. 308 SchemaObjectsCreateHandlerFunc(h.addClass) 309 api.SchemaSchemaObjectsDeleteHandler = schema. 310 SchemaObjectsDeleteHandlerFunc(h.deleteClass) 311 api.SchemaSchemaObjectsPropertiesAddHandler = schema. 312 SchemaObjectsPropertiesAddHandlerFunc(h.addClassProperty) 313 314 api.SchemaSchemaObjectsUpdateHandler = schema. 315 SchemaObjectsUpdateHandlerFunc(h.updateClass) 316 317 api.SchemaSchemaObjectsGetHandler = schema. 318 SchemaObjectsGetHandlerFunc(h.getClass) 319 api.SchemaSchemaDumpHandler = schema. 320 SchemaDumpHandlerFunc(h.getSchema) 321 api.SchemaSchemaClusterStatusHandler = schema. 322 SchemaClusterStatusHandlerFunc(h.getClusterStatus) 323 324 api.SchemaSchemaObjectsShardsGetHandler = schema. 325 SchemaObjectsShardsGetHandlerFunc(h.getShardsStatus) 326 api.SchemaSchemaObjectsShardsUpdateHandler = schema. 327 SchemaObjectsShardsUpdateHandlerFunc(h.updateShardStatus) 328 329 api.SchemaTenantsCreateHandler = schema.TenantsCreateHandlerFunc(h.createTenants) 330 api.SchemaTenantsUpdateHandler = schema.TenantsUpdateHandlerFunc(h.updateTenants) 331 api.SchemaTenantsDeleteHandler = schema.TenantsDeleteHandlerFunc(h.deleteTenants) 332 api.SchemaTenantsGetHandler = schema.TenantsGetHandlerFunc(h.getTenants) 333 } 334 335 type schemaRequestsTotal struct { 336 *restApiRequestsTotalImpl 337 } 338 339 func newSchemaRequestsTotal(metrics *monitoring.PrometheusMetrics, logger logrus.FieldLogger) restApiRequestsTotal { 340 return &schemaRequestsTotal{ 341 restApiRequestsTotalImpl: &restApiRequestsTotalImpl{newRequestsTotalMetric(metrics, "rest"), "rest", "schema", logger}, 342 } 343 } 344 345 func (e *schemaRequestsTotal) logError(className string, err error) { 346 switch err.(type) { 347 case uco.ErrMultiTenancy: 348 e.logUserError(className) 349 case errors.Forbidden: 350 e.logUserError(className) 351 default: 352 e.logUserError(className) 353 } 354 }